15. Three Sum

Three Sum

【題目】

Given an array nums of n integers, are there elements abc in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

(給定一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。)

Note:

The solution set must not contain duplicate triplets.

(注意:答案中不可以包含重複的三元組。)

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]


【分析】

乍一看這道題,最最最最直接暴力的方法是:我們可以採用對a,b,c三層for循環。但是我們提交之後時間複雜度一定會超出題目的時間限制。因爲通常這種題目所給的用例會非常大,這道題暴力求解的時間複雜度是n^3,所以我們應該尋求方法,降低時間複雜度。

所以我們想到這道題目與Two Sum類似,我們可以先用a對數組進行遍歷;因爲題目要求是a + b + c = 0,所以這道題就變成了b + c的值等於-a,然後用之前我寫過的Two Sum那道題的方法就可以了。

上面那種方法的確可以把結果跑出來,但是時間複雜度依然不是很理想,所以今天我想介紹另一種方法,這種方法我在之前的博客中也談到過:用雙向指針。

  1. 首先我們要對數組進行升序排序,然後定義第一個數字a =nums[index]; 對數組nums進行遍歷,所以有: for (index = 0; index < nums.length; index++)
  2. 其次我們需要定義兩個指針,一個從左到右(我定義叫left),另一個從右到左(我定義叫right);left = index + 1(左指針從index = 0的下一個開始)right = nums.length - 1(數組長度減一即爲最後一位,index從0開始)
  3. 我們有其餘兩個數字b和c,b = nums[left], c = nums[right] ,total = a + b + c,在left < right的條件下, 我們分三種情況討論:1. total < 0;  2. total > 0; 3. total = 0
  4. 第一種情況:說明三個數字中需要有一個數字變大,a是遍歷整個數組,在外層,不能動;而c是從右向左移動,數組是升序排序,向左移動只能使結果越來越小,因此只能b向右移動,即:left++; 第二種情況同理,需要有數字變小,a還是不能動,b向右移動只能越來越大,所以只能c向左,即:right--; 第三種情況就是解,需要加到result中,然後左右指針同時移動到下一位即:同時進行 left++和 right--。
  5. 最後我們需要對答案進行去重操作,因爲題目要求是all unique。舉個例子:假如一個數組{-1, -1, -1, 1, 0, -2, 2},我們知道-1,-1,2相加是0。但是我們不知道某一個解中的-1究竟是哪個-1,所以我們應該去重。

Java實現代碼如下:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        for (int index = 0; index < nums.length; index++){
            int a = nums[index];
            if (index >= 1 && nums[index - 1] == a) {
                continue;
            }
            int left = index + 1;
            int right = nums.length - 1;
            while (left < right) {
                int b = nums[left];
                int c = nums[right];
                int total = a + b + c;
                if (total < 0) {
                    left++;
                } else if (total > 0) {
                    right--;
                } else {
                    result.add(Arrays.asList(a, b, c));  //noted
                    while (left < right && b == nums[left + 1]) {
                        left++;
                    }
                    while (left < right && c == nums[right - 1]) {
                        right--;
                    }
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章