代码随想录算法训练营第六天打卡| 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

454.四数相加II  题解细节去看代码随想录

这个题涉及一个概念——元组

并且,此题只要求给出满足条件的元组的个数,而不要求求出具体的数,并且不用去重。

这一题一共有四个数组,要想在四个数组中分别找到一个数字满足四个数字之和为零,单纯的四个for循环时间复杂度为n^4,而使用哈希法的map,将四个数组两两为一组,分为a+b和c+d,用key值记录满足(a+b)+(c+d)=0条件的(a+b)和(c+d)是否出现,用value记录出现的次数。最后用count来记录a+b+c+d=0出现的次数,而这里要注意,count=value之和。即 

key:a+b的数值,value:a+b数值出现的次数

这里再注意一个点,到c+d遍历循环时,我们要在map中找的是等于0-(c+d)的值,因为a+b+c+d=0,所以0-(c+d)=(a+b),在之前a+b遍历循环时,map储存的是(a+b)的值。

383.赎金信

这道题目和242.有效的字母异位词 (opens new window)很像,242.有效的字母异位词 (opens new window)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。

本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。

  • 第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思”  这里说明杂志里面的字母不可重复使用。

  • 第二点 “你可以假设两个字符串均只含有小写字母。” 说明只有小写字母,这一点很重

15.三数之和

这道题的重点,去重,详细的去重逻辑建议去看视频解答

首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。

依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i],b = nums[left],c = nums[right]。

接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。

如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。

18.四数之和  细节看 代码随想录

四数之和与前面的三数之和思想一样,只不过在三数之和的基础上再多加一个类似三数之和中的i

指针一个for循环,即双指针left和right不变,外加两个for循环。但是这个题的关键在于剪枝和去重。回顾三数之和中的剪枝操作

 if (nums[i] > 0) {
                return result;
            }

如果假设四数之和同样写作

if(nums[i] > target)

就不可行了,因为这是在target为正数的情况下可用的,如果target为负数,这个剪枝就不能用了。

可以写成

if(nums[i] > target && (nums[i] >=0 || target >= 0))

之前的哈希表的经典题目:454.四数相加II (opens new window),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。

454.四数相加II (opens new window)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值