1. 题目
给定四个包含整数的数组列表 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 。
类似题目:POJ 2785
2. 解题
- 二分查找,最后一个例子超时
class Solution {
int *ab, *cd;
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int n = A.size(), i, j, k = 0, ans = 0;
int N = n*n;
ab = new int[N];
cd = new int[N];
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
ab[k++] = A[i]+B[j];
k = 0;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
cd[k++] = -C[i]-D[j];
sort(cd,cd+N);
for(i = 0; i < N; ++i)
{
ans += findV(ab[i], N);
}
return ans;
}
int findV(int &val, int &N)
{
int i = 0, j = N-1, mid, count = 0, idx;
while(i <= j)
{
mid = i+((j-i)>>1);
if(val == cd[mid])
{
idx = mid-1;
while(idx >= 0 && cd[idx--] == val)
++count;
idx = mid+1;
while(idx < N && cd[idx++] == val)
++count;
return count+1;
}
else if(val < cd[mid])
j = mid-1;
else
i = mid+1;
}
return 0;
}
};
- 哈希表
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int n = A.size(), i, j, ans = 0;
unordered_map<int, int> m;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
if(m.find(A[i]+B[j]) == m.end())
m[A[i]+B[j]] = 1;
else
m[A[i]+B[j]]++;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
if(m.find(-C[i]-D[j]) != m.end())
ans += m[-C[i]-D[j]];
return ans;
}
};