原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xvpj16/
解法一:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0 ; i < nums.length-2 ; i++) {
// 过滤重复数据
if (i>0 && nums[i] == nums[i-1]) {
continue;
}
// 第一个数据大于0的数不可能存在三数之和为0
if (nums[i] > 0) {
break;
}
// 左指针
int left = i + 1;
// 由指针
int right = nums.length - 1;
// 目标值 因为计算和为0 所以直接取负数 校验是否相等即可
int target = -nums[i];
while (left < right) {
int sum = nums[left] +nums[right];
if (sum == target) {
List<Integer> item = Arrays.asList(nums[i], nums[left], nums[right]);
result.add(item);
while (left < right && nums[left] == nums[left+1]) {
left++;
}
while(left < right && nums[right] == nums[right-1]) {
right--;
}
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return result;
}
}
思路:双指针的思路,首先将数组排序,循环遍历固定数组中的某一个值,然后通过一个左指针和一个右指针分别指向数组中的固定值的下一个值和数组中的最后一个值,左右指针指向的值的和是否与固定值(取反)相等,如果相等就讲这三个值放到返回的集合中并将左指针向后移,右指针向前移,期间需要过滤相同的数据,即与左指针或者右指针相邻的下一个数据如果是相等的,就需要单独移动左指针或者右指针,如果和的值小于固定值,需要单独移动左指针,大于则需要移动右指针。然后遍历一下个值。遍历时需注意,当固定值大于0时,就表示不存在和的值等于固定值的情况了,当固定值的上一个值与其相等时,也许过滤当前的固定值。