文章目录
- 题目介绍
- 解法
题目介绍
解法
思路分析:
先将数组nums排序;然后用一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上,双指针 left和right交替向中间移动,记录对于每个固定指针 i的所有满足 nums[i] + nums[left] + nums[right] == 0 的 left,right 组合:
- 当 i > 0且nums[i] == nums[i - 1]时即跳过此元素nums[i]:因为已经将 nums[i - 1] 的所有组合加入到结果中,本次双指针搜索只会得到重复组合。
- left,right 分设在数组索引 (i,len(nums)) 两端,当left < right时循环计算s = nums[i] + nums[left] + nums[right],并按照以下规则执行双指针移动:
- 当s < 0时,left += 1并跳过所有重复的nums[left];
- 当s > 0时,right -= 1并跳过所有重复的nums[right];
- 当s == 0时,记录组合[k, left, rightj]至res,执行left += 1和right -= 1并跳过所有重复的nums[left]和nums[right],防止记录到重复组合。
代码如下:
class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> ans = new ArrayList<>();int n = nums.length;for (int i = 0; i < n - 2; i++) {int x = nums[i];if (i > 0 && x == nums[i - 1]) continue; // 跳过重复数字int l = i + 1;int r = n - 1;while (l < r) {int sum = x + nums[l] + nums[r]; //三个数之和if (sum > 0) {r--;} else if (sum < 0) {l++;} else {ans.add(List.of(nums[i], nums[l], nums[r]));l++; r--;while (l < r && nums[l] == nums[l - 1]){l++; // 跳过重复数字} while (r > l && nums[r] == nums[r + 1]){r--;// 跳过重复数字} }}}return ans;}
}
法二:
每次添加的时候先判断一下原列表里是否包含,但是会导致超出时间限制。
class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> ans = new ArrayList<>();int n = nums.length;for (int i = 0; i < n - 2; i++) {int x = nums[i];int l = i + 1;int r = n - 1;while (l < r) {int sum = x + nums[l] + nums[r]; //三个数之和if (sum > 0) {r--;} else if (sum < 0) {l++;} else {if( !ans.contains(List.of(x, nums[l], nums[r]))){ans.add(List.of(x, nums[l], nums[r]));} l++; r--;}}}return ans;}
}