刷题 哈希2
代码随想录
LeetCode 454. 四数相加 II
哈希
思路
- 分组求和,再作判断
细节
- 不必使用unordered_multimap,只用计数
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int count = 0;
unordered_map<int, int> m12;
for(int i = 0; i < nums1.size(); ++i){
for(int j = 0; j < nums2.size(); ++j){
++m12[nums1[i] + nums2[j]];
}
}
for(int k = 0; k < nums3.size(); ++k){
for(int l = 0; l < nums4.size(); ++l){
count += m12[0 - nums3[k] - nums4[l]];
}
}
return count;
}
};
LeetCode 383. 赎金信
哈希
思路
- 跟字母异位词相似,本题是包含关系,异位词是相同关系
细节
略
LeetCode 15. 三数之和
排序 #三指针 #双指针 #去重 #难点
思路
- 先排序简化题目
- 确定一个,移动另外两个指针,期间去重
- 由于有序,当sum > 0时,减小c,sum < 0时,增加b
细节
- 如何去重
- 排序
- 迭代跳过
- a去重应保留第一个出现的,跳过后面重复的,而不能跳过前面重复的,保留最后一个。因为后者会漏掉ab相同的情况
LeetCode 18. 四数之和
排序 #四指针 #三指针 #双指针 #去重 #难点
思路
- 与三数和类似,多一层循环
细节
- 去重
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.size() < 4){
return res;
}
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 3; ++i){
if(static_cast<long>(nums[i]) + nums[i + 1] + nums[i + 2] + nums[i + 3] > target){
break;
}
if(i > 0 && nums[i] == nums[i - 1]){
continue;
}
for(int j = i + 1; j < nums.size() - 2; ++j){
if(static_cast<long>(nums[i]) + nums[j] + nums[j + 1] + nums[j + 2] > target){
break;
}
if(j > i + 1 && nums[j] == nums[j - 1]){
continue;
}
int k = j + 1;
int l = nums.size() - 1;
while(k < l){
if(static_cast<long>(nums[i]) + nums[j] + nums[k] + nums[l] > target){
--l;
}
else if(static_cast<long>(nums[i]) + nums[j] + nums[k] + nums[l] < target){
++k;
}
else{
res.push_back({nums[i], nums[j], nums[k], nums[l]});
while(k < l && nums[k] == nums[k + 1]){
++k;
}
while(k < l && nums[l] == nums[l - 1]){
--l;
}
++k;
--l;
}
}
}
}
return res;
}
};