题目:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路:
先进行排序,然后从头到尾开始选择加数sum,在选择的加数后面设置两个头尾指针,搜索相加等于加数sum的相反数的两个,注意选择加数的时候筛选出不同的。
为什么选择的两个被加数是在sum之后?因为如果sum的被加数可以取在前面,而前面已经做过了运算,后面的数也用到了,因此会重复。
为什么选择加数sum一定是负数?如果sum>0,sum相反数<0,没有两个正数相加=负数
package com.test15;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
//-1 3 2
//-1 -5 2 3 6
//1 2 3 4 5
//先进行排序,然后从头到尾(必须是负数)开始选择加数sum,在选择的加数后面设置两个头尾指针,搜索相加等于加数sum的相反数的两个,注意选择加数的时候筛选出不同的。
//为什么选择的两个被加数是在sum之后?因为如果sum的被加数可以取在前面,而前面已经做过了运算,后面的数也用到了,因此会重复。
//为什么选择加数sum一定是负数?如果sum>0,sum相反数<0,没有两个正数相加=负数
public class ThreeSum {
public List<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> list = new HashSet();
if(nums.length==0) return new ArrayList<List<Integer>>(list);
Arrays.sort(nums);//排序
//
// for (int num : nums) {
// System.out.print(num + " ");
// }
// System.out.println();
int pre = nums[0];//作为判断加数重复,记录之前的数
for(int i=0;i<nums.length;i++) {
if(nums[i]==pre && i!=0) continue;
if(nums[i]>0) break;
int front = i+1;
int rail = nums.length-1;
// System.out.println("front:" + front +" rail:" + rail);
while(rail>front) {
if(nums[front]+nums[rail]==-nums[i]) {
// System.out.println("front:" + front +" rail:" + rail);
ArrayList<Integer> ll = new ArrayList<>();
ll.add(nums[front]);
ll.add(nums[rail]);
ll.add(nums[i]);
list.add(ll);
front++;
rail--;//避免了重复
}
else if(nums[front]+nums[rail]<-nums[i]) {
front++;
}
else {
rail--;
}
}
pre = nums[i];//避免了重复
}
return new ArrayList<List<Integer>>(list);
}
public static void main(String[] args) {
int[] nums = {0,0,0,0};
List<List<Integer>> list = new ThreeSum().threeSum(nums);
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.get(i).size(); j++) {
System.out.print(list.get(i).get(j) + " ");
}
System.out.println();
}
}
}