题目
https://leetcode-cn.com/problems/3sum/
解法一-哈希表
想法和之前的四数相加一样。两个for得到所有数字相加的可能,然后看数组中的哪个数字是他们的相反数。最后还要去重。这样是非常费时的,很容易超时,所以我们换一种解法。
解法二-双指针
算法流程:
- 对于数组长度 n,如果数组为 null 或者数组长度小于 3,返回 []。
- 对数组进行排序。
- 遍历排序后数组:
若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
对于重复元素:跳过,避免出现重复解 - 令左指针 L=i+1,右指针 R=n-1,当 L<R 时,执行循环:
- 若和大于 0,说明 nums[R]] 太大,RR 左移
若和小于 0,说明 nums[L] 太小,LL 右移 - 当 nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解(l++;r–)。并同时将 L,R 移到下一位置,寻找新的解.
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if(nums[i]>0){return result;}
if(i>0 && nums[i] == nums[i - 1]){ continue;}
int left = i+1;
int right = nums.length-1;
while(left<right) {
int sum = nums[i] + nums[left] + nums[right];
if(sum>0){
right--;
}else if(sum<0){
left++;
}else {
//sum==0
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
//去重
while (right > left && nums[right] == nums[right - 1]) {right--;}
while (right > left && nums[left] == nums[left + 1]) {left++;}
right--;
left++;
}
}
}
return result;
}