三数之和的算法

记录这道题的原因是我认识到,算法就该是这么优雅的东西啊!

题目描述

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]

满足要求的三元组集合为:

[
  [-1, 0, 1],
  [-1, -1, 2]
]

我不喜欢leetcode,所以并无代码。

思路:

首先,a+b+c=0,我们可以变为 b+c = -a。

将该数组变为有序数组,过程不记录。

第二步:三个变量a、b、c;

a:当前所指向的元素

b:遍历的左侧起始元素

c:遍历的右侧结束元素

第三步:

  1. a从0开始,逐渐右移,就是循环;那么每次右移的过程中,我们需要找到和为-a的b与c;因为结果为0,而数组是有序的,所以a>0时即可结束循环。a向右移时,为了符合上方的题目要求(见红色字体)如果a>0,需要判断arr[a-1]==arr[a],如果等于,那么此元素没有运算的必要,直接continue;
  2. a在一次循环中已经确定,剩余需要确定b和c。b从a开始,c从len-1开始。
    1. 如果b+c>-a,则和需要减小,可以b左移或者c左移,但是b如果左移,则b相当于过去的a,肯定会导致重复的结果集。所以c左移,c本来也是承担了左移的功能;
    2. 如果b+c<-a,则和需要增大,可以b右移或者c右移,这里移动b,和上面相同的思路;
    3. b+c= -a ,这就是我们想要的结果,加进去。
  3. 移动b和c的过程中,和移动a的思路相同,相同的元素直接跳过,避免结果集重复。

可以适用于所有的情况,也不一定非得是0啦。

记于石家庄疫情严重期间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值