Given two integer arrays like this:-
int[] a = { 2, 6, 10, 13, 17,18 };
int[] b = { 3, 7, 8, 9, 11, 15 };
How can I find pai
For ordered (only matters for the detection of the max) arrays with integers > 0 with the help of a modified sieve of Eratosthenes, I think the complexity is O(max * log(max) * log(log(max)) + n) and there is O(max) extra space required (which can be a huge improvement or very bad depending on n and max compared to the standard O(n^2) with O(1) space and no dependency on max):
long total = 0;
int max = (a[a.length - 1] > b[b.length - 1] ? a[a.length - 1] : b[b.length - 1]) + 1;
int[] sieve = new int[max], anti = new int[max], count = new int[max];
for (int i = 1; i < max; i++) {
sieve[i] = i; // using numbers and divide by prime instead of booleans
anti[i] = 1; // number by which i has to be multiplied to get the smallest square
}
for (int i = 2; i < max; i++) {
if (sieve[i] == i) { // i is prime
for (int j = i; j < max; j += i) {
boolean odd = false;
do {
odd = !odd;
sieve[j] /= i;
} while (sieve[j] % i == 0);
if (odd)
anti[j] *= i;
}
} // if you know the max over all the calls the above has only to be done once
} // except for resetting count and total, so we would get O(n) because max is constant
for (int i = 0; i < a.length; i++)
count[anti[a[i]]]++; // hash map for count is better than array if n < max
for (int i = 0; i < b.length; i++)
total += count[anti[b[i]]];
A square number will be mapped to 1 and others to the product of primes with odd exponents in the factorization of the number. In your example every number is mapped to itself except for 8 => 2, 9 => 1, 18 => 2. Other interesting numbers below 18 (not square or mapping to itself): 12 => 3. When iterating over a the algorithm increases the count of 2 once when visiting 2 and once when visiting 18. The total will be increased by 2 when the iteration over b visits 8, the only matches between the two arrays and therefore the end result.