leetcode15_threesum

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

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

示例:

給定數組 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合爲:
[
[-1, 0, 1],
[-1, -1, 2]
]

我們採用分治的思想. 想要找出三個數相加等於0,我們可以對數組依次遍歷, 每一項a[i]我們都認爲它是最終能夠組成0中的一個數字,那麼我們的目標就是找到 剩下的元素(除a[i])兩個相加等於-a[i].

通過上面的思路,我們的問題轉化爲了給定一個數組,找出其中兩個相加等於給定值。找兩個數之間關係的問題一般用雙指針解決即可, 雙指針一般又需要對數組進行排序。 加上我們需要外層遍歷數組,因此總的時間複雜度應該是O(N^2)。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 記住,如果要找兩個數之間的關係,一般都是要用雙指針,這樣只需要一個循環(O(n))
        # 而爲了方便知道怎麼移動指針,需要先排序。
        # 這道題排序不是瓶頸,所以可以用內置算法調用(O(n*logn))解決
        # 排序後,遍歷所有數,對於任何一個數,它以後的那些數字裏面,要找出兩個使得它們的和爲這個數的負數
        # 整個算法的複雜度爲O(n^2)
        result = []
        nums.sort()
        n = len(nums)
        for i in range(n):
            # 已經從小到大排序了,所以如果出現了大於0的數,它後面的數一定都大於0
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i-1]:
                continue
            j = i + 1
            k = n - 1
            #  O(n), 移動指針的循環一般用while
            while j < k:
                if nums[j] + nums[k] == -nums[i]:
                    result.append([nums[i], nums[j], nums[k]])
                    while j < k and nums[j+1] == nums[j]:
                        j += 1
                    while j < k and nums[k-1] == nums[k]:
                        k -= 1
                    j += 1
                    k -= 1
                elif nums[j] + nums[k] < -nums[i]:
                    # 這個時候說明需要一個更大的數
                    j += 1
                else:
                    k -= 1
        return result
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章