?
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: 2Explanation: The two tuples are: 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
?
這道題是之前那道4Sum的延伸,讓我們在四個數組中各取一個數字,使其和為0。那么墜傻的方法就是遍歷所有的情況,時間復雜度為O(n4)。但是我們想想既然Two Sum那道都能將時間復雜度縮小一倍,那么這道題我們使用哈希表是否也能將時間復雜度降到O(n2)呢?答案是肯定的,我們如果把A和B的兩兩之和都求出來,在哈希表中建立兩數之和跟其出現次數之間的映射,那么我們再遍歷C和D中任意兩個數之和,我們只要看哈希表存不存在這兩數之和的相反數就行了,參見代碼如下:
?
解法一:
class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {int res = 0;unordered_map<int, int> m;for (int i = 0; i < A.size(); ++i) {for (int j = 0; j < B.size(); ++j) {++m[A[i] + B[j]];}}for (int i = 0; i < C.size(); ++i) {for (int j = 0; j < D.size(); ++j) {int target = -1 * (C[i] + D[j]);res += m[target];}}return res;} };
?
這種方法用了兩個哈希表分別記錄AB和CB的兩兩之和出現次數,然后遍歷其中一個哈希表,并在另一個哈希表中找和的相反數出現的次數,參見代碼如下:
?
解法二:
class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {int res = 0, n = A.size();unordered_map<int, int> m1, m2;for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {++m1[A[i] + B[j]];++m2[C[i] + D[j]];}}for (auto a : m1) res += a.second * m2[-a.first];return res;} };
?
類似題目:
4Sum
?
參考資料:
https://discuss.leetcode.com/topic/67593/clean-java-solution-o-n-2
https://discuss.leetcode.com/topic/67729/concise-8-line-c-solution-with-hashmap-simple-and-clean/2
?
LeetCode All in One 題目講解匯總(持續更新中...)