1. 程式人生 > >乘風破浪:LeetCode真題_018_4Sum

乘風破浪:LeetCode真題_018_4Sum

乘風破浪:LeetCode真題_018_4Sum

一、前言

    前面我們已經練習過了三個數相加的集合運算,現在變成了四個數,其實道理是一樣的。三個數的時候可以轉成兩個數的加法,最後來解決,而四個數的可以轉換成三個數的加法,最終變成兩個數的加法運算。

二、4Sum

2.1 問題

2.2 分析與解決

    根據我們之前的經驗,可以很自然地想到變成三個數相加來計算,不過因為是四個數相加,因此需要至少3個迴圈了,這樣時間複雜度就是O(n~3)。下面是這種解法。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        if (nums.length == 0) return ans;
        Arrays.sort(nums);
        for (int i = 0; i < nums.length - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            for (int j = i + 1; j < nums.length - 2; j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int k = j + 1, l = nums.length - 1;
                while (k < l) {
                    int sum = nums[i] + nums[j] + nums[k] + nums[l];
                    if (sum < target) k++;
                    else if (sum > target) l--;
                    else {
                        List<Integer> list = new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[k]);
                        list.add(nums[l]);
                        ans.add(list);
                        if (nums[k] == nums[l]) break;
                        while (k + 1 < l && nums[k] == nums[k + 1]) k++;
                        while (l - 1 > k && nums[l] == nums[l - 1]) l--;
                        k++;
                        l--;
                    }
                }
            }
        }
        return ans;
    }
}

 

    另外我們也可以做一些細節上面優化,這裡不再贅述。

三、總結

     對於一些型別題,我們只要理解了一些本質,並且在做題的時候多聯想一些之前的道理,就能輕鬆地做出來了。萬事開頭難,思路是非常重要的。