题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例1
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
示例2
输入:nums = [] 输出:[]
示例3
输入:nums = [0] 输出:[]
做题思路
最直观的方法是三重循环,依次枚举各种情况,但是得到的结果不符合题目所要求的“答案不可以包含重复的三元组”。我们将数组进行排序得到一个升序的数组,当我们枚举出前两个数时,第三个数就已经确定了(c=-a-b),在双重循环中的每重循环都排除一下枚举相同的数。将第三个数的指针初始化为数组最右端,在第二重循环中,当三个数之和大于0时就将第三个数的指针左移,三个数之和等于0就将此时的结果存进去。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int len=nums.length; //获取数组长度
List<List<Integer>> res=new ArrayList<List<Integer>>(); //存放结果
Arrays.sort(nums); //对数组进行排序(升序)
//枚举a
for(int i=0;i<len;i++){
//避免和上次枚举的数相同
if(i>0&&nums[i]==nums[i-1]){
continue;
}
//c对应的指针初始化为指向数组的最右端
int k=len-1;
//枚举b
for(int j=i+1;j<len;j++){
//避免和上次枚举的数相同
if(j>i+1&&nums[j]==nums[j-1]){
continue;
}
//保证b的指针永远在c的指针的左侧,当a+b+c>0时说明c偏大,c的指针左移
while(j<k&&nums[j]+nums[k]>-nums[i]){
k--;
}
//当b的指针和c的指针相撞时退出循环
if(j==k){
break;
}
//a+b+c=0时储存结果
if(nums[i]+nums[j]+nums[k]==0){
List<Integer> list=new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
res.add(list);
}
}
}
return res;
}
}