LeetCode15. 三數之和

稚嫩的勱勱發表於2020-11-17

學習雙指標的運用

題目描述

方法一:暴力解法(三個迴圈)

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        result = []
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                for k in range(j+1, len(nums)):
                    if nums[i] + nums[j] + nums[k] == 0 and [nums[i], nums[j], nums[k]] not in result:
                        result.append([nums[i], nums[j], nums[k]])
        return result

超出時間限制
在這裡插入圖片描述

方法二:排序 + 雙指標

官方解法

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 先排序,為了判斷是否重複
        nums.sort()
        result = []
        for i in range(len(nums)):
            # 對於每一重迴圈而言,相鄰兩次列舉的元素不能相同,否則也會造成重複
            if i == 0 or nums[i] != nums[i-1]:
                # 第三重迴圈對應的指標
                k = len(nums) - 1
                for j in range(i+1, len(nums)):
                    if j == i+1 or nums[j] != nums[j-1]:
                        # 需要保證j在k的左側
                        while nums[i] + nums[j] + nums[k] > 0 and j<k:
                            k -= 1
                        # 如果指標重合,隨著 b 後續的增加,就不會有滿足 a+b+c=0 並且 b<c 的 c 了,可以退出迴圈
                        if j == k:
                            break
                        if nums[i] + nums[j] + nums[k] == 0:
                            result.append([nums[i], nums[j], nums[k]])
        return result

在這裡插入圖片描述
複雜度分析

  • 時間複雜度: O ( N 2 ) O(N^2) O(N2),其中 N N N 是陣列 nums \textit{nums} nums 的長度。
  • 空間複雜度: O ( log ⁡ N ) O(\log N) O(logN)。我們忽略儲存答案的空間,額外的排序的空間複雜度為 O ( log ⁡ N ) O(\log N) O(logN)。然而我們修改了輸入的陣列 nums \textit{nums} nums,在實際情況下不一定允許,因此也可以看成使用了一個額外的陣列儲存了 nums \textit{nums} nums的副本並進行排序,空間複雜度為 O ( N ) O(N) O(N)

相關文章