1st round, 15 3Sum

来源:互联网 发布:mac壁纸轮播 编辑:程序博客网 时间:2024/06/10 14:54

2sum, 3sum 是典型的考查排序后数组的特性的一道题,一旦将数组排序,加和的话就通过 夹逼法 实现就可以。。。

如果数组内有重复数据出现,那么要考虑,是否可以过滤掉一些重复元素,在夹逼过程中,可以滑过一整段相同的数字,而不是每跳到一个数字就计算考察一下。。


public class Solution {    public List<List<Integer>> threeSum(int[] nums) {        List<List<Integer>> list = new  ArrayList<>(); // !!! my knowledge for container is so short        if(nums==null || nums.length<3) return list;                Arrays.sort(nums);        for(int i=0; i<nums.length-2; i++){            while((i>0) && nums[i]==nums[i-1]&& i<nums.length-3) i++;            if(nums.length>3 && i==(nums.length-3) && nums[nums.length-4]==nums[nums.length-3] ) return list;            // NB!!!!!! And the conditions in if() while() matters in ORDER!! safe to put the length first            // this is a FRAGMENT code, added because of an error            //while((i>0) && nums[i]==nums[i-1]&& i<nums.length-3) i++; // i<nums.length-3!! not i<nums.length-2!!            // since I hecked the previous i in last loop, so in order to avoid duplication, I should skip the same nums[] here                        //while(nums[i]==nums[i+1]) i++; // get the last element of a sequence of same element, but this is wrong, since the starting point cannot be ignored, they can be a element!!! the only time you can ignore is when you find the match.                        int l=i+1;            int r=nums.length-1;            while(l<r){                //while(nums[l]==nums[l+1] && (l+1)<r) l++;                //while(nums[r-1]==nums[r] && l<(r-1)) r--;                                int sum=nums[l]+nums[r];                if(sum==-nums[i]){                    List<Integer> item = new ArrayList<>();                    item.add(nums[i]);                    item.add(nums[l]);                    item.add(nums[r]);                    list.add(item);                    while(nums[l]==nums[l+1] && (l+1)<r) l++; // 1: update either l or r is okay, updating both could be a little faster. 2: (l+1)<r !!! since you are in a while loop, you can constantly comparing: nums[l]==nums[l+1]. !!! So keep index with legal bounds                    l++;    // after while loop, l is at the position of last element of sequence of same elem, so have to ++                     //while(nums[l]==nums[l+1] ) l++;                    //while(nums[r-1]==nums[r] ) r--;                    // or r--; does not matter, but have to updata either l or r                }                else if(sum<-nums[i]) l++;                else if(sum>-nums[i]) r--;                            }        }        return list;    }}

我今天写了第二遍,思路比上面的要清晰流畅一些。。。但是要注意的重点是:无论是i还是left,right,都需要先进位,然后再通过while()来判断是否跨过重复元素。。。我在ppt中有所标记,代码如下:


        List<List<Integer>> list= new ArrayList<>();        int len= nums.length;        if(len<3) return list;                Arrays.sort(nums);        for(int i=0; i<len-2; i++){            while(i>0 && i<len-2 && nums[i]==nums[i-1]) i++; // 这里和下面的left,right的处理一模一样,只是说i在每次进for loop都+1了,所以不需要写,想想for就是while的一种简略写法,只不是把i++综合在一起写进来了。。。所以这里只需要直接通过while来判断。。。弄清楚这个了之后的固定i的三种变化情况,==, >, < 都是做同样处理。。。            int left=i+1;            int right=len-1;            while(left<right){                int sum=nums[i]+nums[left]+nums[right];                if(sum==0){                    list.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));/*                    List<Integer> match= new ArrayList<>();                    match.add(nums[i]);                    match.add(nums[left]);                    match.add(nums[right]);                    list.add(match);*/                    //break;  // 这是不能break的,在找到一个match之后,还会有其他match比如,  [1,2,...,8,9] 1+9 和 2+8 都是match                    left++;                    while(left<right && nums[left]==nums[left-1]) left++;                    right--;                    while(left<right && nums[right]==nums[right+1]) right--;                    //while(right>left && nums[right-1]==nums[right]) right--;                }                else if(sum<0){                    //while(left<right && nums[left+1]==nums[left])                     left++;                    while(left<right && nums[left]==nums[left-1]) left++;                }                else{                    //while(right>i && nums[right-1]==nums[right])                     right--;                    while(left<right && nums[right]==nums[right+1]) right--;                }            }        }        return list;







0 0
原创粉丝点击