題目
給定四個包含整數的數組清單 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 。
思考
這一題和LeetCode 18. 四數之和題目相似,但是本質不同。
因為三數之和和四數之和這兩道題目使用哈希法在不逾時的情況下做到對結果去重是很困難的,很有多細節需要處理。
而本題是四個獨立的數組,隻要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考慮有重複的四個元素相加等于0的情況。
回顧之前的兩數之和,其實這邊思路是一緻的。
采用分為兩組,HashMap存一組,另一組和HashMap進行比對。
這樣的話情況就可以分為三種:
1.HashMap存一個數組,如A。然後計算三個數組之和,如BCD。時間複雜度為:O(n)+O(n3),得到O(n3).
2.HashMap存三個數組之和,如ABC。然後計算一個數組,如D。時間複雜度為:O(n3)+O(n),得到O(n3).
3.HashMap存兩個數組之和,如AB。然後計算兩個數組之和,如CD。時間複雜度為:O(n2)+O(n2),得到O(n^2).
三.根據第二點我們可以得出要存兩個數組算兩個數組。
四.我們以存AB兩數組之和為例。首先求出A和B任意兩數之和sumAB,以sumAB為key,sumAB出現的次數為value,存入hashmap中。
然後計算C和D中任意兩數之和的相反數sumCD,在hashmap中查找是否存在key為sumCD。
這段了解來自于guo-sheng-fei
覺得說的挺有條理,直接拿過來用了。
代碼
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
//前面是nums,後面是出現的頻次
unordered_map<int,int> map;
//總組合數目
int count=0;
for(int i=0;i<A.size();i++)
{
for(int j=0;j<B.size();j++)
{
map[A[i]+B[j]]++;
}
}
for(int i=0;i<C.size();i++)
{
for(int j=0;j<D.size();j++)
{
int iter=0-(C[i]+D[j]);
//如果能找到
if(map.find(iter) !=map.end())
{
count+=map[iter];
}
}
}
return count;
}
};