记录这道题的原因是我认识到,算法就该是这么优雅的东西啊!
题目描述
给定一个包含 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:遍历的右侧结束元素
第三步:
- a从0开始,逐渐右移,就是循环;那么每次右移的过程中,我们需要找到和为-a的b与c;因为结果为0,而数组是有序的,所以a>0时即可结束循环。a向右移时,为了符合上方的题目要求(见红色字体)如果a>0,需要判断arr[a-1]==arr[a],如果等于,那么此元素没有运算的必要,直接continue;
- a在一次循环中已经确定,剩余需要确定b和c。b从a开始,c从len-1开始。
- 如果b+c>-a,则和需要减小,可以b左移或者c左移,但是b如果左移,则b相当于过去的a,肯定会导致重复的结果集。所以c左移,c本来也是承担了左移的功能;
- 如果b+c<-a,则和需要增大,可以b右移或者c右移,这里移动b,和上面相同的思路;
- b+c= -a ,这就是我们想要的结果,加进去。
- 移动b和c的过程中,和移动a的思路相同,相同的元素直接跳过,避免结果集重复。
可以适用于所有的情况,也不一定非得是0啦。
记于石家庄疫情严重期间