3 Sum

classic sum problems.
given an array may contains duplicates, return all the unique triplet which sum equals to 0.

a classic way is to presort it, and use three pointers, the first one will be single direction, and the other two will be opposite direction pointer pair.
but how can we make sure that isn’t any duplicate triplet. and we are not saying that we can’t contains any duplicates in triplet. just as a part of final result, triplet duplicates are not allowed.
so the questions converts to: how to identify a triplet as unique among all other triplets?

so how about this: each time we only moves a pointer, if this pointer is duplicate as its last one, then that definitely the same as the last triplets.

so after sometime, this is the code I wrote, but it does not work the way I expect, but from this, you will understand why you are suck at solving algorithm problems.

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        
        if (nums == null || nums.length < 3) return list;
        
        Arrays.sort(nums);
        
        int start = 0;
        int l = start + 1;
        int r = nums.length - 1; //first. instead of assign them this way, you choose to assign them with 0, 1, 2
        while (start <= nums.length - 3) {
            while (l < r) {
                System.out.println("xx");
                if (nums[start] + nums[l] + nums[r] == 0) {
                    //how to shorten the following five lines of code? there must be a way
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[start]);
                    temp.add(nums[l]);
                    temp.add(nums[r]);
                    list.add(temp);
//constantly forget about potential boundary overflow, and since we just want to place the l and r to the first position where they are not exactly the same as before
                    while (l < r && nums[l+1]==nums[l] && nums[r+1]==nums[r]) { //if either of them is not the same, then while will break
                        l++;
                        r--;
                    }
                    l++;
                    r--;
                    
                } else if (nums[start] + nums[l] + nums[r] > 0) { //pretty wise there though, don't need to worry about potential duplicates because we only moving one at a time, if there are same, then next round we will be in this branch again
                    r--;
                } else {
                    l++;
                }
            }
            while (start + 1 < nums.length && nums[start + 1] == nums[start]) {
                start++; //start will remains at the last position of duplicates
            }
            start++;
            
            
        }
        return list;
        
    }
}

actually the code should be like the following:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        
        if (nums == null || nums.length < 3) return list;
        
        Arrays.sort(nums);
        
        int start = 0;
        
        while (start <= nums.length - 3) {
            int l = start + 1;
            int r = nums.length - 1; //this should be within the while Loop!!!!!!
            //System.out.println(start);
            while (l < r) {
                
                if (nums[start] + nums[l] + nums[r] == 0) {
                    
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[start]);
                    temp.add(nums[l]);
                    temp.add(nums[r]);
                    list.add(temp);
                    while (l < r && nums[l+1]==nums[l] && nums[r-1]==nums[r]) { //if either of them is not the same, then while will break
                        l++;
                        r--;
                    }
                    l++;
                    r--;
                    
                } else if (nums[start] + nums[l] + nums[r] > 0) {
                    r--;
                } else {
                    l++;
                }
            }
            while (start + 1 < nums.length && nums[start + 1] == nums[start]) {
                start++; //start will remains at the last position of duplicates
            }
            start++;
            
            
        }
        return list;
        
    }
}

in two words, YOU SUCK

posted @ 2020-09-07 23:48  EvanMeetTheWorld  阅读(11)  评论(0)    收藏  举报