1,题目要求
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 -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.
Example:
Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
Output:
2
Explanation:
The two tuples are:
- (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
- (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
给定四个列表A,B,C,D的整数值,计算有多少元组(i,j,k,l),使得A [i] + B [j] + C [k] + D [1] 是零。
为了使问题更容易,所有A,B,C,D都具有相同的N长度,其中0≤N≤500。所有整数都在-2 28到2 28 - 1的范围内,结果是 保证最多231 - 1。
2,题目思路
对于这道题,给定四个列表,从四个列表中取值,计算有多少和为0的情况。
直接求解,即使用四重for循环,肯定可以求得解,但是速度太慢了,时间复杂度达到惊人的O(n4),肯定不能作为求解思路。
因此,我们可以从之前的Two Sum的思路:
即将两个数的和转化为target与其中一个数字的差,这样,我们就将O(n4)转换为两个O(n2)。
在这里,可以优化的unordered_map的一点是,利用map的count函数,可以减少key值的直接索引,减少实现消耗。
count函数用以统计key值在unordered_map中出现的次数。实际上,c++ unordered_map不允许有重复的key。因此,如果key存在,则count返回1,如果不存在,则count返回0.
3,代码实现
static auto speedup = [](){
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
unordered_map<int, int> abSum;
for(auto &a : A)
for(auto &b : B)
abSum[a+b]++;
int res = 0;
for(auto &c : C)
for(auto &d : D)
if(abSum.count(-c-d)) res+=abSum[-c-d];
return res;
}
};