目录
454四数相加
15三数之和
双指针法
18四数之和
剪枝操作
454四数相加
暴力操作就是四个for循环
这个题目是用哈希表来解答 我们可以将a+b进行一个遍历放到一个数组里面 再将c+d来放到一个数组中 来看一下是否c+d中有a+b所需要的值
由于这个题目是int这种 所以只能从set 和map中进行选hash
但是又由于我们不仅要统计a+b里面有没有出现过 还要统计一下出现的次数 这样的话我们就需要hashmap
在遍历a+b数组的时候我们将a+b的值存储为key并且将出现的次数作为value
在遍历c+d的数组的时候 我们判断0-(c+d)有没有在上面那个集合中出现过没有 出现过的话将次数记录
这样两个for循环 时间复杂度就是n的平方
a+b假如出现了三次五 下面出现了一次5 那么这样的话就是有三个四元组
c++使用unordermap 接下来遍历a+b
接着遍历c+d target=0-(c+d)
id判断map中是否出现过这个target 出现过的话count加上key对应的数值
null. - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/4sum-ii/solutions/499745/si-shu-xiang-jia-ii-by-leetcode-solution
15三数之和
这个题目用哈希法比较复杂 因为需要去重
双指针法
使用双指针的时候一定要对数组先排序 因为他没要求返回下标 只要求返回值
定义一个i left right分别代表a b c
这边先固定i
假设num[i]+num[left]+num{right]>0这样的话需要right向里移动一位 right--
如果三个数相加小于0的话 需要left++
如果等于0的话就是结果 把它加到result二维数组中
这边的细节就是去重 abc三个数都需要去重
我们首先定义一个result存放我们的结果集 对数组排序
遍历这个数组if(number[i]>0)则可以直接返回了没有必要继续开始了 因为数组是排过序的后面肯定都大于0
接下来第一步去重 对a进行去重
这边是有两种判断的情况 num[i]=num[i+1] 或者是num[1]=num[i-1]
这里我们使用的是第二种去重 为什么不使用第一种呢??
假设有一个数组是{-1,-1,2} 当我们使用的是第一种 -1 和-1相等直接返回 但是 这个-1+-1+2满足我们的条件啊 所以说第一种其实是在判断结果集中是否有重复的元素 不满足我们的条件
但是我们使用第二种的话 这个-1+-1+2已经被我们遍历过了 已经存在我们的结果集中了 再去遍历就会发现第二个元素等于第一个元素然后就直接return
对i去重之后就需要对b和c进行操作
收获完结果后需要对b和c进行一个去重
去重的逻辑就是在保证right>left 的基础上 如果right【i】=right【i-1】i一直减减
同理如果left【i】=left【i+1】left++
同时当收获了结果之后 left++ right--同时去操作
去重的逻辑放到我们收获结果逻辑的下面 因为比如说当一个数组是00000当left和right一直移动相等了的话 直接就从刚开始就pass掉了不满足(left>right)这个条件
. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/3sum/solutions/284681/san-shu-zhi-he-by-leetcode-solution
18四数之和
四数之和也就是多了一个k循环 target变成自己的数了
剪枝操作
由于三数之和的要求是target为0 所以三数排序之和i>0就可以直接剪枝return 因为后面越来越大
可是四数之和的话target是自己输入的一个数可能是正数也可能是负数 所以不能那样操作
这里的剪枝只能是num【k】>0同时 num【k】>target同时target>0的时候才能做剪枝 直接break
接下来就是去重的操作 if(k>0&&num【k-1】)直接返回
for循环中的i和三数之和的去重操作一样 就是这边的i也可以继续做一个剪枝
如果i+k相加>0同时i+k相加>target 同时target>0满足这些条件也可以做一个返回