代码随想录算法(哈希表二)

目录

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。icon-default.png?t=N7T8https://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。icon-default.png?t=N7T8https://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满足这些条件也可以做一个返回

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值