当前位置:   article > 正文

三数之和 3Sum leetcode

3sum leetcode

leetcode 15.三数之和 3Sum

第一步:

判断问题类型,观察 信息之间关系,除了暴力求解,是否有稍微更好一点的解法,如果没有用最简单的方法进行暴力求解法

测试中发现有重复问题,解决重复,发现排序才可以更好的解决重复。

以此写出第一个代码

  1. class Solution {
  2. public List<List<Integer>> threeSum(int[] nums) {
  3. //考虑 特殊值,边界值,再优化
  4. //不排序的话 去重很难
  5. Arrays.sort(nums);
  6. List<List<Integer>> result = new ArrayList();
  7. for(int i = 0; i < nums.length-2; i++){
  8. //排序以后的去重,i==0是因为 第一次的值不算重复的
  9. if(nums[i] < 0){
  10. if(i==0 || i>0 && nums[i]!=nums[i-1]){
  11. //剩下两数之和
  12. int sum = 0 - nums[i];
  13. for(int j=i+1; j < nums.length-1; j++){
  14. for(int k = j+1; k < nums.length; k++){
  15. if(nums[j]+nums[k] == sum){
  16. List<Integer> list = new ArrayList();
  17. list.add(nums[i]);
  18. list.add(nums[j]);
  19. list.add(nums[k]);
  20. result.add(list);
  21. }
  22. }
  23. }
  24. }
  25. }
  26. }
  27. return result;
  28. }
  29. }

发现排序后,算法可以更加优化

因为三数之和 与 排序好的数字是有一定关系的。

-7 -3 -2 0 2 3 4 5 6 7

a    b                       c

1.三数全正 全负 pass 如果从最左边开始试起,头部大于0就没有必要算下去了。

2.以第一个数为基准,从数组两边开始寻找值,如果a <0 c<0 停止,a > 0 , c>0 停止

b+c + a > 0 c--

b+c + a < 0 b++

循环得到 等于0 的值

特殊情况:

-7 = 2 5 ,3 4

出现重复值,如何跳过

最终解法

  1. class Solution {
  2. public List<List<Integer>> threeSum(int[] nums) {
  3. //考虑 特殊值,边界值,再优化
  4. //不排序的话 去重很难
  5. Arrays.sort(nums);
  6. List<List<Integer>> result = new ArrayList();
  7. for(int i = 0; i < nums.length-2; i++){ //第一层循环控制第一个基准值
  8. //根据有序数组特性 排除一些无效数组
  9. if(nums[i] > 0 || (nums[i] < 0 && nums[nums.length-1]<0)) return result;
  10. //排序以后的去重,i==0是因为 第一次的值不算重复的
  11. if(i==0 || i>0 && nums[i]!=nums[i-1]){
  12. //剩下两数之和
  13. int sum = 0 - nums[i];
  14. int left = i+1,right = nums.length -1;
  15. while(left < right){
  16. if(nums[left]+nums[right] == sum){
  17. result.add(Arrays.asList(nums[i],nums[left],nums[right]));
  18. //数值相等 需要考虑下一次移动,1.是否有重复数 2.没有重复数怎么移动
  19. //从 -4 = 22 开始 ,左右差值就至少是2了,-7 = 2 53 4为最小差值数
  20. //所以相等后,至少两边都要挪动一位数
  21. while(left < right && nums[left]==nums[left+1] ) left++;
  22. while(left < right && nums[right]==nums[right-1] ) right--;
  23. left++;
  24. right--;
  25. }else if(nums[left]+nums[right] < sum){
  26. //1.考虑左边移动还是右边移动 left + right + num < 0 left++
  27. //2.考虑重复值,知道是左起点移动后,那就是检查左边的重复值
  28. while(left < right && nums[left]==nums[left+1])left++;
  29. left++;
  30. }else{ //可以省略 while(l < r && nums[left]==nums[left+1])left++;
  31. while(left < right && nums[right]==nums[right-1])right--;
  32. right--;
  33. }
  34. }
  35. }
  36. }
  37. return result;
  38. }
  39. }

 

国外大牛解法

  1. class Solution {
  2. public List<List<Integer>> threeSum(int[] nums) {
  3. Arrays.sort(nums);
  4. List<List<Integer>> result = new ArrayList();
  5. for(int i = 0; i < nums.length-2; i++){
  6. if(i == 0 || (i > 0 && nums[i] != nums[i-1]) ){
  7. int left = i+1,right = nums.length -1,sum = 0 - nums[i];
  8. while(left < right){
  9. if(nums[left]+nums[right] == sum){
  10. result.add(Arrays.asList(nums[i],nums[left],nums[right]));
  11. while(left < right && nums[left]==nums[left+1] ) left++;
  12. while(left < right && nums[right]==nums[right-1] ) right--;
  13. left++;right--;
  14. }else if(nums[left]+nums[right] < sum)
  15. left++;
  16. else
  17. right--;
  18. }
  19. }
  20. }
  21. return result;
  22. }
  23. }

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/366068
推荐阅读
相关标签
  

闽ICP备14008679号