#15 3Sum

正确解法:

在排序之后,用for loop确定最小的数,然后让剩下两个指针在最小数的基础上,分列两边,向中间靠拢。

关于重复的考虑:对于最小的指针,只需要保证最小的指针不一样即可。对于另外两个指针,只有在成功塞进结果列的情况下才需要考虑,这时候,只要把重复去掉就好了。

时间复杂度O(n2)。

 

我的问题:

  1. O(n3)次的复杂度:既然我这么用了,其实排序并没有带给我积极的意义。排序本身的作用是利用这一串数字的排列,来减小时间复杂度。

  2. 对于重复的数字,实际有两个bound来决定要不要继续找数字。

    1. 有新的数存在

    2. 在a的基础假设上,以a为动力,来移动指针

→ 用我的方法,存在一个问题,就是当这一串数字的末尾全是重复数字的时候,我无法
预知在后面是否还有新的数字存在。所以,其实从两边向中间的方法就可以解决这个问
题,我只要check左边的指针永远小于右指针就可以了。


修正后的代码:(只作为参考,记录下来)

class Solution {
   public List<List<Integer>> threeSum(int[] nums) {
       List<List<Integer>> result = new ArrayList<>();
       if(nums.length < 3){
           return result;
       }
       Arrays.sort(nums);
       if(nums[0] > 0 || nums[nums.length-1] < 0){
           return result;
       }

       for(int i = 0; i < nums.length - 2; i++){
           if(i == 0 || nums[i - 1] != nums[i]){
               int j = i + 1;
               int k = nums.length - 1;
               while(j < k){
                   if(nums[i] == - (nums[j] + nums[k])){
                       List<Integer> current = new ArrayList<>();
                       current.add(nums[i]);
                       current.add(nums[j]);
                       current.add(nums[k]);
                       result.add(current);
                   
                   
                       // check repeated values
                       while(j < k && nums[j] == nums[j + 1]){
                           j++;
                       }
                       while(j < k && nums[k] == nums[k - 1]){
                           k--;
                       }
                       j++;
                       k--;
                   }else if(nums[i] < - (nums[j] + nums[k])){   
                       // nums[j] + nums[k] can be larger
                       j++;
                   }else{
                       k--;
                   }
               }
           }
           
       }
       return result;
   }

}

猜你喜欢

转载自www.cnblogs.com/yxcindy/p/9938744.html
今日推荐