class Solution:
def numTriplets(self, nums1, nums2):
from collections import Counter
def countPairs(arr1, arr2):
count2 = Counter(arr2)
res = 0
for a in arr1:
target = a * a
for b in count2:
if target % b == 0:
c = target // b
if c in count2:
if b == c:
res += count2[b] * (count2[b] - 1) // 2
elif b < c:
res += count2[b] * count2[c]
return res
return countPairs(nums1, nums2) + countPairs(nums2, nums1)
class Solution {
public:
int numTriplets(vector<int>& nums1, vector<int>& nums2) {
return countPairs(nums1, nums2) + countPairs(nums2, nums1);
}
int countPairs(vector<int>& arr1, vector<int>& arr2) {
unordered_map<long long, int> freq;
for (int n : arr2) freq[n]++;
int res = 0;
for (int a : arr1) {
long long target = 1LL * a * a;
for (auto& [b, cnt_b] : freq) {
if (target % b == 0) {
long long c = target / b;
if (freq.count(c)) {
if (b == c)
res += cnt_b * (cnt_b - 1) / 2;
else if (b < c)
res += cnt_b * freq[c];
}
}
}
}
return res;
}
};
class Solution {
public int numTriplets(int[] nums1, int[] nums2) {
return countPairs(nums1, nums2) + countPairs(nums2, nums1);
}
private int countPairs(int[] arr1, int[] arr2) {
Map<Long, Integer> freq = new HashMap<>();
for (int n : arr2) freq.put((long)n, freq.getOrDefault((long)n, 0) + 1);
int res = 0;
for (int a : arr1) {
long target = 1L * a * a;
for (long b : freq.keySet()) {
if (target % b == 0) {
long c = target / b;
if (freq.containsKey(c)) {
if (b == c)
res += freq.get(b) * (freq.get(b) - 1) / 2;
else if (b < c)
res += freq.get(b) * freq.get(c);
}
}
}
}
return res;
}
}
var numTriplets = function(nums1, nums2) {
function countPairs(arr1, arr2) {
let freq = new Map();
for (let n of arr2) freq.set(n, (freq.get(n) || 0) + 1);
let res = 0;
for (let a of arr1) {
let target = a * a;
for (let [b, cnt_b] of freq.entries()) {
if (target % b === 0) {
let c = target / b;
if (freq.has(c)) {
if (b === c)
res += cnt_b * (cnt_b - 1) / 2;
else if (b < c)
res += cnt_b * freq.get(c);
}
}
}
}
return res;
}
return countPairs(nums1, nums2) + countPairs(nums2, nums1);
};
Given two integer arrays nums1
and nums2
, your task is to count the number of triplets where:
a
from nums1
, and two elements b
and c
from nums2
(they can be the same or different indices), such that a * a = b * c
.a
from nums2
, and two elements b
and c
from nums1
, such that a * a = b * c
.
The order of b
and c
does not matter, but distinct pairs of indices are counted separately. You cannot reuse the same element for both b
and c
unless they are at different indices.
At first glance, the problem looks like a brute-force candidate: for every element in one array, try all possible pairs in the other array and check if the equation holds. However, this would be too slow for large arrays, since the number of pairs grows quadratically.
To optimize, we recognize that for a given a
, we want to count the number of pairs (b, c)
such that b * c = a * a
. This is a classic case for using a hash map to count frequencies, so we can efficiently check for the required products.
We also need to be careful to avoid counting duplicate pairs when b
and c
are the same, and to count each unordered pair only once.
a
in the first array, compute target = a * a
.
b
in the second array, check if target % b == 0
(to ensure c
is an integer).
c = target / b
. If c
is also in the frequency map, count the pairs:
b == c
: The number of pairs is freq[b] * (freq[b] - 1) / 2
(choose 2 from freq[b]).b < c
: The number of pairs is freq[b] * freq[c]
.b ≤ c
to avoid double-counting unordered pairs.nums1
and nums2
, and sum the results.
This approach leverages hash maps for O(1) lookup and avoids unnecessary recomputation, making it much more efficient than brute-force.
Suppose nums1 = [7,4]
and nums2 = [5,2,8,9]
.
a = 7
in nums1
: target = 49
.
(b, c)
in nums2
where b * c = 49
.nums2
so no pairs.a = 4
: target = 16
.
nums2
. There is 1 occurrence of each, so 1 pair.a
in nums2
, check pairs in nums1
.
a = 8
: target = 64
.nums1
.a = 9
: target = 81
.nums1
.a = 2
: target = 4
.nums1
.a = 5
: target = 25
.nums1
.The key to solving this problem efficiently is recognizing that counting pairs with a product equal to a square can be reduced to counting frequencies of factors, which is ideal for hash maps. By iterating over one array and using the frequency map of the other, we avoid redundant work and achieve a much faster solution than brute-force. The approach is both simple and powerful, making good use of hash maps and careful counting logic to avoid overcounting.