问题
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