Find pairs in two arrays such that when multiplied becomes a perfect square

后端 未结 4 825
不知归路
不知归路 2021-01-23 05:11

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

4条回答
  •  情歌与酒
    2021-01-23 06:16

    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.

提交回复
热议问题