代码随想录训练营|第六天 哈希表进阶

代码随想录训练营|第五天 哈希表进阶

四数相加

给出四个数组,每个数组中选一个元素,最终满足和条件
在这里插入图片描述

这里很精妙的一个思路就是较为递归的思路,将四元组变成了两个两元组,这样就和之前的找和问题思想类似了

在这里插入图片描述

不要求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的九次方了,确实很容易超时呢
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值