from collections import Counter
class Solution:
def fourSumCount(self, A, B, C, D):
ab_sum = Counter()
for a in A:
for b in B:
ab_sum[a + b] += 1
count = 0
for c in C:
for d in D:
target = -(c + d)
count += ab_sum.get(target, 0)
return count
#include <unordered_map>
#include <vector>
using namespace std;
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> ab_sum;
for (int a : A) {
for (int b : B) {
ab_sum[a + b]++;
}
}
int count = 0;
for (int c : C) {
for (int d : D) {
int target = -(c + d);
if (ab_sum.count(target)) {
count += ab_sum[target];
}
}
}
return count;
}
};
import java.util.HashMap;
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
HashMap<Integer, Integer> abSum = new HashMap<>();
for (int a : A) {
for (int b : B) {
abSum.put(a + b, abSum.getOrDefault(a + b, 0) + 1);
}
}
int count = 0;
for (int c : C) {
for (int d : D) {
int target = -(c + d);
count += abSum.getOrDefault(target, 0);
}
}
return count;
}
}
var fourSumCount = function(A, B, C, D) {
const abSum = new Map();
for (let a of A) {
for (let b of B) {
abSum.set(a + b, (abSum.get(a + b) || 0) + 1);
}
}
let count = 0;
for (let c of C) {
for (let d of D) {
const target = -(c + d);
if (abSum.has(target)) {
count += abSum.get(target);
}
}
}
return count;
};
The 4Sum II problem asks you to count the number of quadruplets (one element from each of four integer arrays) whose sum is zero.
Given four integer arrays A
, B
, C
, and D
of length n
, compute how many tuples (i, j, k, l)
exist such that:
A[i] + B[j] + C[k] + D[l] == 0
Constraints:
n
(1 ≤ n ≤ 500).
The most direct way to solve this problem is to check every possible quadruplet by looping through all indices i
, j
, k
, and l
. However, this brute-force approach means n^4
total combinations, which is computationally infeasible for n = 500
.
To optimize, we look for ways to reduce the number of combinations we need to check. Notice that the sum can be split into two parts:
(A[i] + B[j]) + (C[k] + D[l]) == 0
If we know all possible sums of A[i] + B[j]
and all possible sums of C[k] + D[l]
, we can look for pairs that add up to zero.
By using a hash map to store the frequencies of sums from the first two arrays, we can efficiently count how many ways the remaining two arrays can "complete" the sum to zero. This is a classic example of using space (hash map) to save time.
Here’s a step-by-step breakdown of the optimized solution:
A[i] + B[j]
:
A
and B
.C[k] + D[l]
:
-(C[k] + D[l])
.Why use a hash map? Hash maps provide constant-time lookup and allow us to efficiently count how many ways the first two arrays can contribute to a sum that can be "completed" by the second two arrays.
Let’s walk through an example with small arrays:
A = [1, 2]
B = [-2, -1]
C = [-1, 2]
D = [0, 2]
Step 1: Compute all A[i] + B[j]
sums and their frequencies:
The hash map is: {-1: 1, 0: 2, 1: 1}
C[k] + D[l]
, look for the complement in the hash map:
Total quadruplets: 1 (from -1+0) + 1 (from -1+2) = 2
Brute-force approach:
A[i] + B[j]
sums: O(n2) time.C[k] + D[l]
sums and looks up complements: O(n2) time.A[i] + B[j]
sums.This makes the problem tractable even for the largest input sizes allowed by the constraints.
The key insight for 4Sum II is to split the four-array sum into two pairs, use a hash map to store the sums of the first pair, and efficiently count complements from the second pair. This reduces an otherwise intractable O(n4) problem to a much more efficient O(n2) solution, making it feasible for large inputs. The approach is elegant because it leverages hash maps for fast lookup and counting, turning a brute-force search into a clever, scalable algorithm.