leetcode454. 4Sum II

Time:2020-6-16

Title Requirements

Given four lists A, B, C, D of integer values, compute how many tuples`(i, j, k, l)`there are such that`A[i] + B[j] + C[k] + D[l]`is zero.

To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228to 228\- 1 and the result is guaranteed to be at most 2^31- 1.

**Example:**

**Input:**
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

**Output:**
2

**Explanation:**
The two tuples are:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

There are four equal length and unordered array of integers. First, it is required to take a number from each of the four arrays so that their sum is 0. Then, it is asked how many sets of numbers satisfy the conditions.

Ideas and codes

Using some merging and sorting ideas, if we calculate the result that all the numbers in a and B can form, and then calculate the result of all the numbers in C and D, we only need to find out whether there is a corresponding negative number in CD for the value in ab. In addition to recording the sum of array elements, it also records that the sum has occurred several times. The code is as follows:

    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        if (A==null || A.length == 0) return 0;

        Map<Integer, Integer> sumMapAB = new HashMap<>(A.length * B.length);
        Map<Integer, Integer> sumMapCD = new HashMap<>(C.length * D.length);

        for (int i = 0 ; i<A.length ; i++) {
            for(int j = 0 ; j<B.length ; j++) {
                sumMapAB.put(A[i] + B[j], sumMapAB.getOrDefault(A[i] + B[j], 0) + 1);
                sumMapCD.put(C[i] + D[j], sumMapCD.getOrDefault(C[i] + D[j], 0) + 1);
            }
        }
        int count = 0;
        for (Integer key : sumMapAB.keySet()) {
            if (sumMapCD.containsKey(-key)) {
                count += sumMapAB.get(key) * sumMapCD.get(-key);
            }
        }
        return count;
    }

The space complexity can be optimized here. In fact, we can save the sum of CD elements in disorder. We only need to go to ab sum to find out whether there is a corresponding negative number each time we calculate the sum of C and D elements.

    public int fourSumCount2(int[] A, int[] B, int[] C, int[] D) {
        if (A==null || A.length == 0) return 0;

        Map<Integer, Integer> sumMapAB = new HashMap<>(A.length * B.length);

        for (int i = 0 ; i<A.length ; i++) {
            for(int j = 0 ; j<B.length ; j++) {
                sumMapAB.merge(A[i] + B[j], 1, Integer::sum);
            }
        }
        int count = 0;
        for (int c : C) {
            for (int d : D) {
                count += sumMapAB.getOrDefault(-c-d, 0);
            }
        }
        return count;
    }