Java习题中 四数相加 & 三数之和 & 四数之和

关于 四数相加
  • 如果用list代替哈希表来进行记录会超时?
    因为一个数组是n的数据量,两个数组元素相加后产生的数据量会变成2n,即list的数据量有2n。两层循环list就是 4n方,这个复杂度可能系数大了被卡了。

关于 三数之和
  • 对于continue和break在三数之和的区别: continue是下一个i 还存在有可能的情况, break是无论后面多少个i我们是确定不会再出现这样的情况了
  • 三数之和去重为什么碰到相邻相同的要元素跳过:
    一个是因为之前已经判断过,不必再判断,还有一个是因为必须要减枝,不然会超时,还有就是题目要求不能重复,再次执行会导致重复添加数据。
  • 三数之和这么去重,是怎么保证a的去重,而没有把合适的b也去掉了呢?
    因为b在a后面,当a的数字确定,后面b+c的值也确定,比如序列-2,-2,4,8,16,第一次遇到某一个a=-2的时候已经把后面所有b+c=2的情况跑完了,第二次再次遇到a=-2的时候已经没有跑的意义了,更遑论有没有去掉合适的b,而且有可能第一次遇到a=-2的时候,可能正好有b=-2,c=4这种情况,但你第二次遇到a=-2,再去跑,就会发现甚至这种情况还会被漏掉。 nums[i] == nums[i-1]基本就是应对这两种情况
  • 对于哈希法b和c去重的逻辑

对于 b 的去重,一般可以和 a 一样检查当前的 b 是否和前一个 b 相同,如果相同,则跳过当前的 b。这样可以保证每个 b 只被使用一次。但是这种方法有一个问题,就是如果数组中有连续三个或以上相同的元素,那么第一个和第二个元素都会被跳过,导致漏掉一些可能的解。例如,如果数组中有三个0,那么[0,0,0]就是一个有效的解,但是用这种方法就会被忽略。

为了解决这个问题,可以改进一下条件,只有当当前的 b 和前两个 b 都相同时才跳过当前的 b。这样可以保 证至少有一个 b 被使用,并且不会出现重复。

对于 c 的去重,利用哈希集合的特性,在找到一个 c 后将其从哈希集合中删除。这样可以保证每个 c 只被使用一次且不会出现重复。

关于 四数之和
  • 四数之和里针对剪枝的if语句进行了讨论,在第二层剪枝中使用if(nums[k] + nums[i] > target && nums[i] > 0)剪枝范围会更大~ (原本是if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0))大家视自己理解方便进行选择即可~
  • 四数之和中, 我们j > i + 1等后面一系列操作不会导致一直跳过的, 至少会取4个数!
  • 剪枝条件必须要加,leetcode上有一组[100000, 100000, 100000, 100000]的输入,target为-2^31,这组数据应该输出空数组,但是这四个数相加会溢出等于-2^31次方,然后输出[100000, 100000, 100000, 100000]的四元组,这是错误的,所以剪枝条件必须要加,判断 nums[k] + nums[i] 是正数又大于target后,可以直接return,因为排序后正数往后都是正数了,相加只会越来越大,没理由能找到满足target的四元组。
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

念君思宁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值