三数之和 3Sum leetcode

leetcode 15.三数之和 3Sum

三数之和 3Sum leetcode_第1张图片

第一步:

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

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

以此写出第一个代码

class Solution {
    public List> threeSum(int[] nums) {
        //考虑 特殊值,边界值,再优化
        //不排序的话 去重很难
        Arrays.sort(nums);
        List> result = new ArrayList();
        for(int i = 0; i < nums.length-2; i++){
            //排序以后的去重,i==0是因为 第一次的值不算重复的
            if(nums[i] < 0){
                 if(i==0 || i>0 && nums[i]!=nums[i-1]){
                //剩下两数之和
                int sum = 0 - nums[i]; 
              for(int j=i+1; j < nums.length-1; j++){
                for(int k = j+1; k < nums.length; k++){
                    if(nums[j]+nums[k] == sum){
                        List list = new ArrayList();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[k]);
                        result.add(list);
                    }
                 }
                }
            }
            }
               
        }
        return result;
    }
}

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

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

-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

出现重复值,如何跳过

最终解法

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

 

三数之和 3Sum leetcode_第2张图片

国外大牛解法

class Solution {
    public List> threeSum(int[] nums) {
        Arrays.sort(nums);
        List> result = new ArrayList();
        for(int i = 0; i < nums.length-2; i++){ 
            if(i == 0 || (i > 0 && nums[i] != nums[i-1]) ){
                int left = i+1,right = nums.length -1,sum = 0 - nums[i];   
                while(left < right){
                    if(nums[left]+nums[right] == sum){
                        result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                        while(left < right && nums[left]==nums[left+1] ) left++;
                        while(left < right && nums[right]==nums[right-1] ) right--;
                        left++;right--;
                    }else if(nums[left]+nums[right] < sum)
                        left++;
                    else
                        right--;
                }
            } 
        }
        return result;
    }
}

 

 

 

 

 

你可能感兴趣的:(算法)