代码随想录第七天| 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

454.四数相加Ⅱ

因为只需要输出四个数合等于零的次数,不需要输出四个数具体是什么,所以相对简单
思路就是,先遍历A,B数组,将A+B放入一个unordered_map里。至于为什么是map,因为不仅需要知道a+b的值是多少,还需要知道a+b的次数,所以用map。又unordered_map效率高,所以。
然后遍历C,D,用同样的方式得到c+d。然后每当c+d=0-(a+b)的时候,count就要+上unordered_map对应的value。

383.赎金信

法一 暴力解法
两层for循环,第一层遍历magazine,第二层遍历ransomNote,如果有字母相等,就在ransomNote中删掉对应字母。最后赎金信为空就返回true。
注意第一层是杂志,否则第一层是赎金信的话,删除字母时没办法每次删掉对应位置的字母。

法二 哈希解法
和242.有效的字母异位词很像,区别是那个要求互相组成,这个只要求a组成b,不要求b组成a
思路就是遍历杂志,对应的字母在record中+1,然后遍历赎金信,对应的字母-1,当record有字母出现负值时,就证明杂志中的某个字母小于赎金信对应字母了,返回false,否则为true。

15.三数之和

法一 哈希解法(不推荐)
去重逻辑太复杂了,比如我现在还不知道为什么元素b的去重要这样:

for (int j = i + 1; j < nums.size(); j++) {
                if (j > i + 2
                        && nums[j] == nums[j-1]
                        && nums[j-1] == nums[j-2]) { // 三元组元素b去重
                    continue;
                }

为什么相较与a,要多比一个啊

法二 双指针法
先进行一个排序,因为并不需要返回下标
然后对a进行去重,记得是if (i > 0 && nums[i] == nums[i - 1])而不是if (i > 0 && nums[i+1] == nums[i])。因为这样是判断结果集里有没有重复元素,比如{-1,-1,2}就被排除掉了。
然后判断三个数和>0了,right就–。<0了,就left++。
当=0了,需要进行b和c的去重:

while (right > left && nums[right] == nums[right - 1]) right--;
 while (right > left && nums[left] == nums[left + 1]) left++;

去重之后,双指针同时收缩。
之前还想为什么不能只变其中一个,后来反应过来要求的是sum=0,只变一个不可能得0.
然后说要注意去重一定要在至少收获一个结果之后进行,否则像{0,0,0,0}就被pass掉了。

四数之和

感觉还是难的。和三数之和相比,需要在最外层加一层for循环。难点仍然是剪枝和去重操作
一级剪枝处理:if(nums[k]>target && nums[k]>0)
一级去重处理:if(k>0 && nums[k]==nums[k-1])第一次写的时候,就忘了加k>0的条件,运行时间超时
二级剪枝处理:if(nums[k]+nums[i]>target && nums[k]+nums[i]>0)将nums[k]+nums[i]看做是一个整体
二级去重处理:if(k>i+1 && nums[i]==nums[i-1])第一次忘了加k>i+1,会运行超时
在定义了left和right之后,需要一个while循环:while(right>left)不然报错
再注意nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出,所以强制变为(long)
当四数之和==target时,一定要先将数push到result之后,再进行去重操作
去重操作别忘了加上判断:while(right>left)
其他和三数之和基本相同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值