2014年5月12日星期一

Loop Approach Solution - 4Sum

The idea is to narrow down 4 to 2, by two extra outside loops. The hard part is to avoid duplicated, by three different necessary moves: skip directly by skipping 0 case (-1), skip from second iteration by default pre value to -1 and set it in iterations, skip by a while loop for all pre on both sides(++ and --). Sort is must have before all operations.

Details is to notice the loop condition. And only loop ranges after the current index at outside loop is sufficient!

public class Solution {
    public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) {
        if(num == null || num.length < 4){
            return new ArrayList<ArrayList<Integer>>();
        }
        ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
        Arrays.sort(num);
     
        for(int s1 = 0; s1 < num.length - 3; s1++){
            if(s1 > 0 && num[s1] == num[s1 - 1]){ //Skip 0 case
                continue;
            }
            int curT = target - num[s1];
            int preS2 = -1;  //record previous position of s2 [0,0,0,0] vs [1, 0, 0, 0, 0] aroused this idea (fail either before)
            for(int s2 = s1 + 1; s2 < num.length - 2; s2++){ //Track previous s2 but need to start checkin at the second loop to not touch s1, that is why set pre first... the first iteration skips checks
                if( preS2 != -1 && num[s2] == num[preS2]){
                    continue;
                }
                preS2 = s2;
                int curTarget = curT - num[s2];
                int s3 = s2 + 1;
                int s4 = num.length - 1;
                while(s3 < s4){
                    if(num[s3] + num[s4] > curTarget){
                        s4--;
                    }else if(num[s3] + num[s4] < curTarget){
                        s3++;
                    }else{
                        ArrayList<Integer> result = new ArrayList<Integer>();
                        result.add(num[s1]);
                        result.add(num[s2]);
                        result.add(num[s3]);
                        result.add(num[s4]);
                        results.add(result);
                        while(++s3 < --s4 && num[s3] == num[s3 - 1] && num[s4] == num[s4 + 1]); //Skip duplicates
                    }
                }
            }
        }    
        return results;
    }
}

没有评论: