题目来源
题目描述
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
}
};
题目解析
和之前的[三数之和]不同的是,它给出了四个独立的数组,只要找出nums[i] + nums[j] + nums[k] + nums[l] = 0即可。而且题目没有要求找出不重复的四元组,这就不需要考虑去重,在难度上降低了。注意nums[x]中数字可能会重复
最朴素的解法是:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int n = nums1.size(), cnt = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
for (int l = 0; l < n; ++l) {
long t = nums1[i] + nums2[j] + nums3[k] + nums4[l];
if(t == 0){
++cnt;
}
}
}
}
}
return cnt;
}
};
会超时。怎么办呢?用“分组+哈希”降低时间复杂度,算法如下:
- 初始化哈希表
- 分组:nums1和nums2分为一组、nums3和nums4分为一组
- 分别对nums1和nums2进行遍历,将所有nums1和nums2的值的和作为哈希表的key,和的次数作为哈希表的value
- 分别对 nums3 和 nums4 进行遍历,若 -(nums3[k] + nums4[l]) 在哈希表中,则四元组次数 +hash[-(nums3[k]+nums4[l])] 次。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int n = nums1.size();
int tmp = 0, cnt = 0;
std::map<int, int> hash;
//统计两个数组中的元素之和,同时统计出现的次数,放入map
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
tmp = nums1[i] + nums2[j];
++hash[tmp];
}
}
//统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
tmp = nums3[i] + nums4[j];
if(hash.count(0 - tmp)){
cnt += hash[0-tmp];
}
}
}
return cnt;
}
};