给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题摘要:
三个数求和与两个有序数组求和类似,采用双指针法,不同的是,三个数求和是将其中的一个数换成nums[i] 中的值,然后剩下的数组值,取其中两个求和如果等于第三个数,则成立。
代码展示:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Janson
* @version 1.0
* @date 2020/6/7 22:44
*/
public class ThreeSum {
public static List<List<Integer>> threeSum(int[] nums){
//注意:因为需要在本类中调用,所以添加了static,如果没有,不能被调用
List<List<Integer>> result = new ArrayList<>();//用于存储后边产生的数组值
if(nums.length<3||nums==null){
return result;
}
Arrays.sort(nums);
//开始查找符合要求的值
for (int i=0;i<nums.length;i++){
if (nums[i]>0){
//因为这个数组是有序数组,如果nums[i]大于0,后边的值都将大于0,三数之和不可能为0
return result;
}
//去重
if (i>0&&nums[i]==nums[i-1]){
continue;
}
int L = i+1; //左指针
int R = nums.length-1; //右指针
//注意,此处是: -nums[i],因为我们后边是:nums[L]+nums[R] == target
int target = -nums[i];
while (L<R){
if(nums[L]+nums[R] == target){
//注意此处,不能直接将nums[i]添加到result列表中
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[L]);
list.add(nums[R]);
result.add(list);
//双指针查找时,也要去重
while (L<R&&nums[L]==nums[L+1]) L++;
while (R>L&&nums[R]==nums[R-1]) R--;
R--;
L++;
}else if(nums[L]+nums[R] > target){
R--;
}else {
L++;
}
}
}
return result;
}
public static void main(String[] args){
int[] nums = {-1, 0, 1, 2, -1, -4};
System.out.println(threeSum(nums));
}
}