Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 454. 4Sum II #454

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 454. 4Sum II #454

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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:
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 那道都能将时间复杂度缩小一倍,那么这道题使用 HashMap 是否也能将时间复杂度降到 O(n2) 呢?答案是肯定的,如果把A和B的两两之和都求出来,在 HashMap 中建立两数之和跟其出现次数之间的映射,那么再遍历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;
    }
};

 

下面这种方法用了两个 HashMap 分别记录 AB 和 CB 的两两之和出现次数,然后遍历其中一个 HashMap,并在另一个 HashMap 中找和的相反数出现的次数,参见代码如下:

 

解法二:

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://leetcode.com/problems/4sum-ii/

https://leetcode.com/problems/4sum-ii/discuss/93920/Clean-java-solution-O(n2)

https://leetcode.com/problems/4sum-ii/discuss/93925/Concise-C%2B%2B-11-code-beat-99.5

 

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant