自用
public class ThreeSum {
//找出所有和为0且不重复的三元组
public List<List<Integer>> threeSum(int[] nums){
//数组长度
int n = nums.length;
//将数组排序
Arrays.sort(nums);
//third指针指向数组末尾
int third = n-1;
//装载三元组的容器
List<List<Integer>> ans = new ArrayList<List<Integer>>() ;
//最外层循环,遍历数组中的每一个元素
for (int first = 0; first < n; first++) {
//num[first] == nums[first-1]能够去掉重复的三元组,为什么呢
//因为如果num[first-1]=1,遍历它时找到了三元组{1,0,-1},那么遍历nums[first]同样也会得到这个三元组
//所以如果前后两个元素相同就直接跳过当前元素就好了
if(first>0 && nums[first] == nums[first-1]){
continue;
}
//下面nums[second] + nums[third] >target再讲为什么是-nums[first]
int target = -nums[first];
//内层循环从fist的下一个元素开始遍历
for (int second = first; second < n; second++) {
//与上面一样,去重,去遍历下一个元素
if(second >first +1 && nums[second] == nums[second-1]){
continue;
}
//因为数组是排过序的,所以nums[third]就是数组中最大的数,而target是三元组中第一个数的相反数 target = -nums[first]
//如果nums[second] + nums[third] == target,那么此时nums[second] + nums[third] + nums[first]不就为0了吗
//为什么要nums[second] + nums[third] >target呢?因为nums[third]已经是最大的数了,所以我们让third向前遍历
//这样才有可能让nums[second] + nums[third] == target
while(second < third && nums[second] + nums[third] >target){
third--;
}
//为什么second==third就退出整个for循环进行下次first遍历
// 而不是像上面那样用continue结束本次循环然后遍历下一个second呢
//我们先分析为什么会second == third,出现这种情况只有nums[second] + nums[third] >target
//因为只有nums[second] + nums[third] >target才能进入上面的while循环,让thrid--到和second相同
//说明直到second==third也没能让nums[second] + nums[third] = target
//那还有种情况就是当second==third时,nums[second] + nums[third] = target怎么没有考虑呢
//这时second==third指向同一个位置,如果这也算的话那不就返回一个两元组了吗
//回到最初的问题,为什么是break而不是continue?
//举个简单的例子 1+5>2 1+4>2 1+3>2... 1相当于second 5相当于third 然后因为nums[second] + nums[third] >target,所以它一直在--
//那如果此时是continue的话就会遍历到下一个second 此时会变成 3+5>2 ,可以发现最小的third都无法满足条件,你继续增加second的值就更不可能满足了
//所以后面的second就没有必要遍历了
if (second == third){
break;
}
if(nums[first] + nums[second] +nums[third] == 0){
List<Integer> list = new ArrayList<>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
}
}
}
return ans;
}
public static void main(String[] args) {
ThreeSum ts = new ThreeSum();
int[] nums = {-3,2,4,0,-2,-1,1};
List<List<Integer>> lists = ts.threeSum(nums);
for (List<Integer> list : lists) {
System.out.println(list);
}
}
}
方法中判断条件的解析已写在代码中