给定四个列表A,B,C,D的整数值,计算有多少元组(i,j,k,l),使得A [i] + B [j] + C [k] + D [l]为零。
为了使问题更容易,所有A,B,C,D具有相同的N长度,其中0≤N≤500。所有整数都在-228到228-1的范围内,结果保证是最多231 - 1。
示例:
Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出: 2
说明: 这两个元组是:
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
我想出了一个解决方案,它连接所有向量并找到4个和。但我知道有更好的解决方案。有人会解释更好的解决方案吗?我只是看到使用O(N ^ 2)的代码,但我无法理解它。
答案 0 :(得分:2)
这是我的O(n^2)
解决方案:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int n = A.size();
int result = 0;
unordered_map<int,int> sumMap1;
unordered_map<int,int> sumMap2;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
int sum1 = A[i] + B[j];
int sum2 = C[i] + D[j];
sumMap1[sum1]++;
sumMap2[sum2]++;
}
}
for(auto num1 : sumMap1) {
int number = num1.first;
if(sumMap2.find(-1 * number) != sumMap2.end()) {
result += num1.second * sumMap2[-1 * number];
}
}
return result;
}
核心观察是 - 如果W + X + Y + Z = 0
然后W + X = -(Y + Z)
。
这里我在(A,B)和(C,D)两个可能的总和中使用了两个哈希表来查找此总和的出现次数。
然后,对于每个sum(A, B)
,我们可以找到sum(C, D)
是否包含可确保sum(A, B) + sum(C, D) = 0
的免费额。添加(sum(a, b)
)*的出现次数*(免费sum(c,d)
的出现次数)到结果中。
创建sum(A, B)
和sum(C, D)
将花费O(n^2)
时间。计算元组的数量为O(n^2)
,因为每对(n^2
,A-B
)总和为C-D
。其他操作(如插入和搜索哈希表)是分摊O(1)
。因此,整体时间复杂度为O(n^2)
。