LeetCode #18. 4Sum プログラミング練習

問題:
f:id:stlisacity:20180518134030p:plain

難易度: medium
入力: int型Array
目的: 入力された整数の内、和がtargetになる四つの整数の組み合わせをすべて出力せよ
出力: int型リストのリスト

#15の3Sumの延長問題です。
基本思想は全く同じで、♯15を解けた人なら同じ方法で解けると思います。
入力された整数の順序がバラバラなのでまずはソートする事をお勧めします。
私の答えはO(n^3)なのでソートしてもTime Complexityへの影響はないですが、
もしO(n*logn)以下の回答がある場合はソートがボトルネックとなってしまうので避けましょう。

注意すべき事: 

  • テストケースによっては重複した答えが多数存在するのでスキップすること


以下回答です。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        int len = nums.length;
        if (len<4) return result;
        for (int i=0; i<len; i++) {
            for (int j=i+1; j<len; j++) {
                    int left = j+1;
                    int right = len-1;
                while (left < right) {
                    int res = nums[i] + nums[j] + nums[left]+ nums[right];
                    if (res == target) {
                        List<Integer> ans = new ArrayList<Integer>();
                        ans.add(nums[i]);
                        ans.add(nums[j]);
                        ans.add(nums[left]);
                        ans.add(nums[right]);
                        result.add(ans);
                        while (i+1<len && nums[i] == nums[i+1]) i++;
                        while (j+1<len && nums[j] == nums[j+1]) j++;
                        while (left+1<len && nums[left] == nums[left+1]) left++;
                        while (right-1>0 && nums[right] == nums[right-1]) right--;
                        left++;
                        right--;
                    }
                    if (res - target < 0) left++;
                    if (res - target > 0) right--;
                }
            }
        }
        return result;
    }
}

まず入力されたArrayをソートします。
ソートされたArrayをForでまわします。
i番目の数字を固定し、右側から和がtargetになる対象数字を探します。
3Sumとの唯一の違いは固定する数字が二つある事です。
leftとrightポインタを用意し、leftはi+1の数字から、rightは最後尾から。
和がtarget以上だったらright--,以下だったらleft++を繰り返します。
対象の組み合わせを見つけた場合はresにリストを追加していきます。
最後に重複を防ぐ為に同じ数字はスキップしておきます。
Time ComplexityはO(n^3)です。

今日は以上。
よいプログラミング生活を!