4个数组中4个整数的和

Sum of 4 integers in 4 arrays

本文关键字:4个 数组 整数      更新时间:2023-10-16

给定A, B, C, D四个整数值列表,计算有多少个元组(i, j, k, l)使得A[i] + B[j] + C[k] + D[l]为零

为了使问题简单一点,所有a, B, C, D都有相同的长度N,其中0≤N≤500。所有的整数都在-228到228 - 1的范围内,并且保证结果最多为231 - 1。

的例子:

Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

输出:2

解释:这两个元组是:

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

我刚刚想出了一个解决方案,将所有向量连接起来并找到4的和。但我知道有更好的解决办法。有人能解释一个更好的解决方案吗?我只看到用0 (N^2)的代码,但我看不懂。

这是我的O(n^2)解决方案:

int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
    int n = A.size();
    int result = 0;
    unordered_map<int,int> sumMap1;
    unordered_map<int,int> sumMap2;
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j) {
            int sum1 = A[i] + B[j];
            int sum2 = C[i] + D[j];
            sumMap1[sum1]++;
            sumMap2[sum2]++;
        }
    }
    for(auto num1 : sumMap1) {
        int number = num1.first;
        if(sumMap2.find(-1 * number) != sumMap2.end()) {
            result += num1.second * sumMap2[-1 * number];
        }
    }
    return result;
}

核心观测值是- if W + X + Y + Z = 0 then W + X = -(Y + Z)

在这里,我对(A, B)和(C, D)中每个可能的和使用了两个哈希表,找到这个和的出现次数。

那么,对于每个sum(A, B),我们可以找到sum(C, D)是否包含保证sum(A, B) + sum(C, D) = 0的互补和。将(sum(a, b)的出现次数)*(互补sum(c,d)的出现次数)与结果相加

创建sum(A, B)sum(C, D)将占用O(n^2)时间。计算元组的数量是O(n^2),因为每对(A-B, C-D)都有n^2和。哈希表上的插入和搜索等其他操作按O(1)平摊。因此,总体时间复杂度为O(n^2)