LeetCode 15题 -> 三数之和
1. 题目描述
-
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
-
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4] 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
2. 解题思路
- 排序+双指针:
- ①如果数组为空或数组元素小于3,返回数组;
- ②排序,
- ③遍历排序后的数组,如果nums[i] > 0,即后面不可能有三个数加起来为0,跳出循环,直接返回结果;
- ④判断数组元素与上一个元素是否相同,如果相同,跳过,避免出现重复的解;
- ⑤左右指针left、right,left = i + 1; right = nums.length - 1;当left < right,执行以下循环:
- ⑥当sum = nums[i] + nums[left] + nums[right] == 0,判断左右指针left、right分别与其下个位置是否重复,去除重复解,并将left、right同时向下个位置移动;
- ⑦当sum = nums[i] + nums[left] + nums[right] > 0,说明nums[right]太大了,因此将右指针right向下个位置移动(左移);
- ⑧当sum = nums[i] + nums[left] + nums[right] < 0,说明nums[left]太小了,因此将左指针left向下个位置移动(右移)。
3. 代码实现
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ThreeSum {
public static List<List<Integer>> threeSum(int[] nums){
List<List<Integer>> ans = new ArrayList<>();
if(nums.length < 3 || nums == null){
return ans;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if(nums[i] > 0){
break;
}
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){
ans.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(left < right && nums[left] == nums[left + 1]){
left = left + 1;
}
while(left < right && nums[right] == nums[right - 1]){
right = right - 1;
}
left = left + 1;
right = right - 1;
}else if(sum > 0){
right = right - 1;
}else{
left = left + 1;
}
}
}
return ans;
}
public static void main(String[] args) {
int[] nums = {-1, 0, 1, 2, -1, -4};
System.out.println(threeSum(nums));
}
}