15. 三数之和
描述
链接
15. 三数之和 - 力扣(LeetCode) (leetcode-cn.com)
解法
去重的时候,注意:
left是逐渐增加的,应该与 过去的自己(比自己小一) 的作比较;
right是从length-1开始逐渐减小的,应该与 过去的自己(比自己大一) 的作比较。
1 class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> ans = new ArrayList<>(); 4 if (nums == null || nums.length <3) { 5 return ans; 6 } 7 Arrays.sort(nums); 8 9 for (int i = 0; i < nums.length -2; i++) { 10 if (nums[i] > 0 ) { 11 break; 12 } 13 if (i > 0 && nums[i] == nums[i-1]) { //去重 14 continue; 15 } 16 int target = -nums[i]; 17 int left = i + 1, right = nums.length - 1; 18 while (left < right) { 19 if (nums[left] + nums[right] == target) { 20 ans.add(new ArrayList<>(Arrays.asList(nums[i],nums[left],nums[right]))); 21 22 left++; 23 right--; 24 while (left < right && nums[left] == nums[left-1]) { //去重 25 left++; 26 } 27 while (left < right && nums[right] == nums[right+1]) { //去重 28 right--; 29 } 30 }else if(nums[left] + nums[right] < target){ 31 left++; 32 }else{ 33 right--; 34 } 35 } 36 } 37 return ans; 38 } 39 }
// 下方的 去重过于 复杂,推荐上方的解法
1 class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> res = new ArrayList<>(); 4 Arrays.sort(nums); 5 6 for (int i = 0; i < nums.length; i++) { 7 if(nums[i] > 0) return res; 8 if (i > 0 && nums[i] == nums[i-1]) continue; // 去重 9 10 int left = i+1, right = nums.length - 1; 11 while (left < right) { 12 int sum = nums[i] + nums[left] + nums[right]; 13 if(sum < 0) { 14 while( left < right && nums[left] == nums[++left]); //去重 15 } 16 else if(sum > 0) { 17 while( left < right && nums[right] == nums[--right]); //去重 18 } 19 else{ 20 List<Integer> tmp = new ArrayList<>(); 21 tmp.add(nums[i]); 22 tmp.add(nums[left]); 23 tmp.add(nums[right]); 24 res.add(tmp); 25 //res.add(new ArrayList<Integer>(Arrays.asList(nums[i], nums[left], nums[right]))); 26 while( left < right && nums[left] == nums[++left]); //去重 27 while( left < right && nums[right] == nums[--right]); //去重 28 } 29 } 30 } 31 return res; 32 } 33 }
有个问题
容易混淆的解法
正确解法,但下述的 去重比较复杂,且容易把 去重
nums[left] == nums[++left]);
nums[right] == nums[--right]);
误写为
nums[left] == nums[left++]); // 注意 left++ 与 ++left的区别
nums[right] == nums[right--]);
或者误写为
nums[--right] == nums[right]);
都得不到完整的答案。
------------------------
添加结果少一个,在于 nums[right--] == nums[right]; 以及 nums[--right] == nums[right]; 是不对的。
需要仔细思考 nums[right] == nums[--right] 和 nums[left] == nums[++left] 的边界条件,比较复杂!
1 class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> res = new ArrayList<>(); 4 Arrays.sort(nums); 5 6 for (int i = 0; i < nums.length; i++) { 7 if(nums[i] > 0) return res; 8 if (i > 0 && nums[i] == nums[i-1]) continue; // 去重 9 10 int left = i+1, right = nums.length - 1; 11 while (left < right) { 12 int sum = nums[i] + nums[left] + nums[right]; 13 if(sum < 0) { 14 while( left < right && nums[left] == nums[left++]); //去重 15 } 16 else if(sum > 0) { 17 while( left < right && nums[right--] == nums[right]); //去重 18 } 19 else{ 20 List<Integer> tmp = new ArrayList<>(); 21 tmp.add(nums[i]); 22 tmp.add(nums[left]); 23 tmp.add(nums[right]); 24 // res.add(tmp); 25 res.add(new ArrayList<>(tmp)); 26 while( left < right && nums[left] == nums[left++]); //去重 27 while( left < right && nums[right--] == nums[right]); //去重 28 } 29 } 30 } 31 return res; 32 } 33 }
结果
题解链接