题目描述
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
注意:
三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)
解集中不能包含重复的三元组。
例如,给定的数组 S = {-10 0 10 20 -10 -40},解集为(-10, 0, 10) (-10, -10, 20)
1. 代码
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author LanceQ
* @version 1.0 2021/4/24 16:09
*/
public class Triad {
public static void main(String[] args) {
int[] nums={-2,0,1,1,2};
int[] S = {-10,0,10,20,-10,-40};
ArrayList<ArrayList<Integer>> arrayLists = threeSum(nums);
System.out.println(arrayLists);
System.out.println(threeSum(S));
}
private static ArrayList<ArrayList<Integer>> threeSum(int[] nums) {
ArrayList<ArrayList<Integer>> res=new ArrayList<>();
if(nums==null||nums.length<3){
return res;
}
Arrays.sort(nums);
for(int i=0;i<nums.length-2;i++){
if(nums[i]>=0){
break;
}
if(i>0&&nums[i]==nums[++i]){
continue;
}
int left=i+1;
int right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum==0){
ArrayList<Integer> list=new ArrayList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
res.add(list);
while (left<right&&nums[left]==nums[left+1]){
left++;
}
while (left<right&&nums[right]==nums[right-1]){
right--;
}
left++;
right--;
}else if(sum<0){
left++;
}else {
right--;
}
}
}
return res;
}
}
运行结果:
[[-2, 0, 2], [-2, 1, 1]]
[[-10, -10, 20], [-10, 0, 10]]
2. 思路:
-
首先需要对数组进行判断,题目要求的是满足条件的三元数组,如果数组为空或者数组里面的个数小于3的话,那就不用找了,一定不会有满足条件的存在。
-
对数组进行排序;
-
从0开始对数组进行遍历,一直遍历到倒数第三个,因为到了倒数第二个的时候,后面只有一个数了,也不可能满足条件的。
-
在循环开始的时候,对第一个进行判断,如果第一个要进行判断的数大于0的话,就跳出循环,不用继续找了,因为这是排序后的数组,如果第一个都大于0的话,后面的值比这个值大,也一定会大于0,不可能存在a+b+c=0的情况。
-
如果“nums[i]==nums[i-1]”,则跳过这个值,因为该题目的条件“不能包含重复的三元组”,相等意味着该值可能存在的三元组已经在上一个数就添加了,所以可以跳过。
-
选取当前值的后一位作为左指针,数组的最后一个值作为右指针,,分别向右、向左移动比对。
-
如果在移动的过程中,出现”nums[i]+nums[left]+nums[right]=0“,就可以添加进链表里面了。
-
添加完之后,由于存在条件“不能包含重复的三元组”,所以比对左边和右边各自的下一个值是否与其相等,相等的话,就分别++或者–跳过该值。
-
最后要记住,操作完7、8的步骤后,需要对左指针和右指针分别进行left++和right–的操作,否则的话,就会停在这里,while不停的判断和list的添加,从此进入了死循环。
-
如果”nums[i]+nums[left]+nums[right]>0“,就表示加起来的值大了,右指针需要左移。
-
如果”nums[i]+nums[left]+nums[right]<0“,就表示加起来的值小了,左指针需要右移。
参考链接:https://blog.csdn.net/luzhensmart/article/details/113471947