给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/3sum
- 首先,满足nums[i] + nums[j] + nums[k] == 0。则由此可以想到排序,然后想到最笨的方法for的三次循环。
- for的三次循环的效率是n的3次方,因此要想另外的方法
- 犹豫不决先排序,步步逼近双指针
- 通过答案中不可以包含重复的三元组,要在代码中去重。
- 由此可以想到双指针进行运算。
public List<List<Integer>> threeSum(int[] nums) {
//首先进行排序 默认是升序
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
//如果第一个元素就>0,肯定是不满足的。(排序后)
if (nums[i] > 0) {
break;
}
//nums[i]==nums[i-1]的值是相同的话,遍历的结果跟前一个是一样的,去重。直接下一个。提高效率
if(i>0&&nums[i]==nums[i-1]){
continue;
}
//定义指针指向i的下一个
int j = i + 1;
//定义指针指向最后一个元素,由于是排序后的,可以根据sum的结果进行指针移动
int k = nums.length - 1;
//移动的范围
while (j < k) {
//求出和
int sum = nums[i] + nums[j] + nums[k];
//如果和<0,则j指针需要向右移动,使sum增大。并且如果向右移动值相同,直接跳过。
if (sum < 0) {
while(j<k&&nums[j]==nums[++j]) {
;
}
} else if (sum > 0) {
while(j<k&&nums[k]==nums[--k]) {
;
}
} else {
/* ArrayList<Integer> list1 = new ArrayList<>();
list1.add(nums[i]);
list1.add(nums[j]);
list1.add(nums[k]);
list.add(list1);*/
//数组可以直接声明,赋值更加方便。
list.add(Arrays.asList(nums[i],nums[j],nums[k]));
//判断是否在这个区间内,并且去重
while(j<k&&nums[j]==nums[++j]) {
;
}
while(j<j&&nums[k]==nums[--k]) {
;
}
}
}
}
return list;
}