4个数组中4个整数的和
Sum of 4 integers in 4 arrays
给定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)
。
相关文章:
- 如何在C++中比较两个char数组
- 在c++中获取两个大int,并将它们存储在数组中
- 如何以优化的方式同时迭代两个间距不相等的数组
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 如何从txt文件中读取多个不同长度的数组?
- C++,数组有多少个地址?
- 将字符串拆分为标记,并将标记拆分为两个单独的数组
- 为什么 2 个相同数组的元素彼此相等
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 可以将两个相同类型的连续数组视为一个数组吗?
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 如何创建一个所有行大小不同的 2D 数组,并且用户将指定每行将有多少个元素?
- C++递归来决定数组中的两个值
- 具有 2 个分量的数组的特征映射到 3 的向量
- C++ 2D 数组写入多个位置
- 如何将字符串和整数读取到两个单独的动态数组中的程序编写?
- 给定一个大小为 N 的数组 S,检查是否可以将序列拆分为两个序列
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- VTK 图像数据,访问数组中的 1 个图像
- 需要使用模板查找数组的第二个最小和最小值