1. 程式人生 > >leetcode-15. 3Sum

leetcode-15. 3Sum

題意:

給出一個數組,在其中找到三個數,之和為0,輸出所有的解。

例子:輸入S = [-1, 0, 1, 2, -1, -4],

輸出[
[-1, 0, 1],
[-1, -1, 2]
]

錯誤嘗試一:

三層迴圈- –超時

正確做法:確定一個數,再用雙指標法找剩餘兩個數

beadt 91%

  • 陣列由小到大排序
  • 遍歷每一個數num,若num不等於他之前的數(等於那麼無需判斷,已經判斷過),那麼,在他之後的子陣列找到兩個數,使之和為num的相反數opp
如何找他之後的兩個數?
  • 兩個指標,一個指向子陣列頭,一個指向尾,
    1. 如果和大於opp,那麼high–,
    2. 如果和小於opp,那麼low++
    3. 如果和==opp,那麼加入res,並且!!!判斷下一個數是否相等nums[low] nums[high,如果相等,無需進行計算直接low++ 或者high–
  • 直到兩指標相遇

Tips:

  • 將多個整數生成一個list:Arrays.asList(num[i], num[lo], num[hi])
  • 如果成功找到組合並且nums[low] == nums[low + 1]或者nums[high] == nums[high - 1],即有重複組合,那麼直接low++ 或者high–,直至該數字無重複。
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        int len = nums.length;
        if (len < 3 || nums[0] > 0 || nums[len - 1] < 0) {// skip same result
            return res;
        }
        for
(int i = 0; i < len - 2; i++){ if (i > 0 && nums[i] != nums[i - 1]) { continue; } int low = i + 1; int high = len - 1; int opp = 0 - nums[i]; while (low < high) { int sum = nums[low] + nums[high]; if (sum < opp) low++; else if(sum > opp) high--; else { res.add(Arrays.asList(nums[i], nums[low], nums[high])); while(low < high && nums[low] == nums[low + 1])// skip same result low++; while(low < high && nums[high] == nums[high - 1])// skip same result high--; low++; high--; } } } return res; }