Count pairs in array whose sum is divisible by the given number

Given an array of integers A and an integer B,
find and return the number of pairs in A whose sum is divisible by B.

Since the answer may be large, return the answer modulo (10^9 + 7).



Input Format

The first argument given is the integer array A.
The second argument given is the integer B.

Output Format

Return the total number of pairs for which the sum is divisible by B modulo (10^9 + 7).

Constraints

1 <= length of the array <= 100000
1 <= A[i] <= 10^9 
1 <= B <= 10^6

For Example

Input 1:
    A = [1, 2, 3, 4, 5]
    B = 2
Output 1:
    4

Input 2:
    A = [5, 17, 100, 11]
    B = 28
Output 2:
    1
思路

我的思路是根据A中的最大最小值,建立一个B有可能的值的范围。
比如说
A = [1, 2, 3, 4, 5]
B = 2
那么这里B最小可能是2,最大是10。然后iterate 2, 4, 6 ,8, 10,再iterate sorted A,找x + y = B。

Solution:

Time: O(B*nlogn)
Space: O(1)

public class Solution {
    public int solve(ArrayList<Integer> A, int B) {
        Collections.sort(A);
        int size = A.size();
        if (size == 1) return 0;
        int max = (A.get(size - 1) + A.get(size - 2)) / B;
        int min = (A.get(0) + A.get(1)) / B;
        int count = 0;
        for (int i = min; i < max; i ++) {
            int p = i + 1;
            for (int j = 0; j < A.size(); j ++) {
                int curr = A.get(j);
                int x = p * B - curr;
                int yIndex = Collections.binarySearch(A, x);
                if (yIndex >= 0) {
                    int l = yIndex;
                    int r = yIndex + 1;
                    while (r < A.size() && A.get(r) == x) {
                        if (r != j) {
                            count ++;
                        }
                        r ++;
                    }
                    while (l >= 0 && A.get(l) == x) {
                        if (l != j) {
                            count ++;
                        }
                        l --;
                    }
                }
            }
        }
        return (count / 2) % (int) (10e9 + 7);
    }
}

思路2

将element bucket到n % B,然后我们就可以用bucket[i] * bucket[B - i]来计算有多少个pair可以加起来整除B了。
注意有两个edge case,一个是bucket[0],还有是bucket[B / 2]当B是偶数的时候。

Solution:

Time: O(n)
Space: O(k)

public class Solution {
    public int solve(ArrayList<Integer> A, int B) {
        //  A = [1, 2, 3, 4, 5]
        //  B = 2
        //      [0 1]
        //      [2 3]
        // 0 : 2 * 1 / 2
        // 1 : 3 * 2 / 2
        long[] freq = new long[B];
        for (int i = 0; i < A.size(); i ++) {
            int n = A.get(i);
            freq[n % B]++;
        }
        long sum = freq[0] * (freq[0] - 1) / 2;
        if (B % 2 == 0) {
            sum += freq[B / 2] * (freq[B / 2] - 1) / 2;
            for (int i = 1; i <= B / 2 - 1; i ++) {
                sum += freq[i] * freq[B - i];
            }
        } else {
            for (int i = 1; i <= B / 2; i ++) {
                sum += freq[i] * freq[B - i];
            }
        }
        return (int) (sum % 1000000007);
    }
}