题源: 454. 四数相加 II
题目的核心是求解四个数组nums1
,nums2
,nums3
, 和nums4
中所有元素组合(a, b, c, d)
的数量,使得它们的和为 0。这道题可以通过哈希表来优化查找和计算过程,减少时间复杂度。
解题思路
-
构建哈希表:
首先,遍历数组nums1
和nums2
,计算所有可能的两数之和,并将这些和存储在一个哈希表中(以和为键,出现次数为值)。这一步是为了记录每一种可能的两数之和及其出现的次数,为后面的匹配操作提供便利。 -
计算匹配和:
然后,遍历数组nums3
和nums4
,对于每对(c, d)
,计算-(c + d)
,查找这个值是否已经作为键存在于哈希表中。如果存在,说明找到了对应的(a, b)
组合,使得a + b + c + d = 0
。将哈希表中该键的值(即(a, b)
组合出现的次数)累加到结果count
中。 -
返回结果:
遍历完成后,count
中存储的就是所有满足a + b + c + d = 0
的四元组组合的数量。
时间复杂度
- 构建哈希表的时间复杂度为
O(N^2)
,其中N
是单个数组的长度(假设所有数组长度相等)。这是因为需要遍历nums1
和nums2
的所有元素组合。 - 查找和匹配的时间复杂度同样为
O(N^2)
,因为需要遍历nums3
和nums4
的所有元素组合,并进行哈希表查找操作。
因此,整体时间复杂度为 O(N^2)
。
空间复杂度
- 哈希表的空间复杂度最坏情况下也为
O(N^2)
,这取决于nums1
和nums2
两数之和的不同结果数量。
Code
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> map;
for(int a : nums1)
for(int b : nums2)
map[a + b] ++;
int count = 0; //记录a + b + c + d = 0的次数
for(int c : nums3)
for(int d : nums4)
if(map.find(0 - (c + d)) != map.end())
count += map[0 - (c + d)];
//map[0 - (c + d)]的值代表所有使得 a + b = -(c + d) 的 (a, b) 对的数量,不能简单写为count ++
return count;
}
};