代码随想录训练营|第五天 哈希表进阶
四数相加
给出四个数组,每个数组中选一个元素,最终满足和条件
这里很精妙的一个思路就是较为递归的思路,将四元组变成了两个两元组,这样就和之前的找和问题思想类似了
不要求key有序的话都可以使用unorder_map节省空间
为什么map不用初始化value为0,因为map定义的时候是定义了一个空的容器,直到后面有插入时才会插入值
为什么可以0-(c+d)?万一(c+d)的值等于同一个,只是c,d不同了,岂不是加了两次?nono本题并没有说组成和里的元素不能重复,所以c,d一改变,始终顺序改变了,也就是不同的生成方法了
三数之和
上一题的进阶版本,只给了一个数组
这里,则需要对生成的数组做去重操作,其细节很多,耗时也很多,所以采用新的双指针办法会更好
注意,一般这种题,将数组提前排好序会事半功倍!
双指针将n的三次方的复杂度降为了n的二次方
易错:去重的逻辑判断这里,比较前一个而不是比较后一个!
题目四:四数之和
题目变化的点在于0变为target,则剪枝操作需要修改,三数之和变成四数之和,因此需要借助两重循环来做
奇怪的报错?
我不明白有什么不一样
但我的就是会超时
class Solution {
public:
vector<vector> fourSum(vector& nums, int target) {
vector<vector> result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();++i){
if(nums[i]>target&&nums[i]>=0) break;
if(nums[i]==nums[i-1]&&i>0) continue;
for(int j=i+1;j<nums.size();++j){
if(nums[i]+nums[j]>target&&nums[i]+nums[j]>=0) break;
if(nums[j]==nums[j-1]&&j>i+1) continue;
int left=j+1;
int right=nums.size()-1;
while(right>left){
if((long)nums[i]+nums[j]+nums[left]+nums[right]>target) right–;
else if((long)nums[i]+nums[j]+nums[left]+nums[right]<target) {left++;}
else
{
result.push_back(vector{nums[i],nums[j],nums[left],nums[right]});
while (right > left && nums[right] == nums[right - 1]) right–;
while (right > left && nums[left] == nums[left - 1]) left++;
}
right–;
left++;
}
}
}
return result;
}
};
把顺序做了一个改变,竟然神奇般的就通过了???
这样也能通过,所以其实就是先算的超限了的原因呢,导致不同类别数相互比较了
毕竟nums[i]都10的九次方了,确实很容易超时呢