问题
Given two arrays a and b of size n. I have to choose one element from a and two elements from b such that. a[i] * a[i] = b[j] * b[k].
I am able to find BruteForce in O(n^2 log(n)) traversing both the arrays and binary searching the value. But dont know how to improve it even more.
How do I count all these number where elements range from 1 <= a[i] <= 10^6 and 1 <= n <= 10^6.
回答1:
Well, I can think in a O(n²) solution.
unordered_multiset S = {}
for each element B in b {
S = S ∪ B
}
First of all, we store all elements of b in a unordered_multiset. Such structure can find elements in O(1) time and if you add 2 or more equal elements, it also knows.
for each element B in b {
for each element A in a {
if( A² % B != 0 ) continue; //making sure it's divisible
let occurrencies = number_of_occurrencies(A² / B, S);
if( occurrencies > 0 ) { //if (A² / B) is in S
if( A == B and ocurrencies > 1 ) {
//your answer is A, B and B
}
else if ( A != B ) {
//your answer is A, B and A² / B
}
}
}
}
Here you loop over both arrays. The main goal is to check, for each element in b, which elements it must be multiplied for in order to be equal to some element of a squared. The, it checks if the element B needs is already in S.
There is a little trick in that. If A = 30 and B = 30, it means that you want to have another 30 in b who's not B. That's the reason of the multiset. If there is only one 30 in the whole set, you know that you are trying to match B with itself, and you can't do that, hence you have to have at least 2 elements valued 30 in b.
来源:https://stackoverflow.com/questions/60224579/searching-triplets-in-two-arrays