给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。
例如:
输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum-ii
方法1:
执行用时 :180 ms, 在所有 C++ 提交中击败了92.69% 的用户
内存消耗 :29.5 MB, 在所有 C++ 提交中击败了56.86%的用户
(1)如果数组是空,直接返回0;
(2)对数组排序,如果数组第一个之和大于0或者最后一个之和小于0,无解,返回0.
(3)创建一个map,放入CD之和以及次数。
(4)遍历AB,看之和是否等于DC之和,等于,直接加上CD之和的次数。
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int res = 0;
if(A.size() < 1) return res;
sort(A.begin(),A.end());
sort(B.begin(),B.end());
sort(C.begin(),C.end());
sort(D.begin(),D.end());
if(A.front()+B.front()+C.front()+D.front() > 0 ||
A.back()+B.back()+C.back()+D.back() < 0 ) return res;
unordered_map<int,int> record;
for(int i = 0; i < C.size(); i++){
for(int j = 0; j < D.size(); j++){
record[C[i]+D[j]]++;
}
}
for(int k = 0; k < A.size(); k++){
int complent = 0 - A[k];
for(int k1 = 0; k1 < B.size(); k1++){
int complent1 = complent - B[k1];
if(record.count(complent1))
res += record[complent1];
}
}
return res;
}
};
方法二:创建两个map
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int res = 0;
if(A.size() < 1) return res;
unordered_map<int,int> sum1,sum2;
for(int i = 0; i < A.size(); i++)
for(int j = 0; j < B.size(); j++)
sum1[A[i]+B[j]]++;
for(int i = 0; i < C.size(); i++)
for(int j = 0; j < D.size(); j++)
sum2[C[i]+D[j]]++;
for(unordered_map<int,int>::iterator iter = sum1.begin(); iter != sum1.end();iter++){
if(sum2.count(-(iter->first)))
res = res + (iter->second * sum2[-(iter->first)]);
}
return res;
}
};