求和問題

LeetCode題目彙總:

1.兩數求和

15. 三數求和

16. 最接近的三數和

18.四數求和

 

兩數求和:

思路:哈希表思想,用python中的dict字典實現,時間複雜度:O(n)

    def twoSum(self, nums ,target) :
        dict_num = {}
        for ids, num in enumerate(nums):
            if target-num in dict_num:
                return [dict_num[target-num], ids]
            dict_num[num] = ids

三數求和:

思路:外循環先固定一個數,在此數之後,用雙指針左(i+1)右(l-1),向中間聚,依次掃描

   def threeSum(self, nums) :
        l = len(nums)
        nums=sorted(nums) # 從小 --> 大
        res= []
        for i in range(0,l-1):
            if nums[i] > 0: break # 縮短時間
            # 保證同一個數只固定一次,既相同數的最後一次出現
            if i > 0 and nums[i] == nums[i - 1]: continue
            left,right = i+1,l-1 # 定義左右指針
            while left < right:
                s = nums[i]+nums[left]+nums[right]
                if s==0:
                    res.append([nums[i],nums[left],nums[right]])
                    # 保證左右指針掃描時,相同數只選一次
                    while left<right and nums[left]==nums[left+1]: left+=1
                    while left<right and nums[right]==nums[right-1]: right-=1
                    # 要好好理解,此時的left,right已經用過了,上面只是移動用過的left,right,在此基礎上再+-
                    left+=1
                    right-=1
                elif s<0 :
                    while left<right and nums[left]==nums[left+1]: left+=1
                    left += 1
                else :
                    while left<right and nums[right]==nums[right-1]: right-=1
                    right-=1
        return res

最接近的三數和:

思路:同三數求和一樣,雙指針,若abs(temp-target)<abs(min_num-target)說明temp更接近目標,更新min_num

 def threeSumClosest(self, nums,target) -> int:
        l = len(nums)
        # 特判,對於數組長度 l,如果數組爲Null或者數組長度小於3,返回 None。
        if not nums or l < 3: return None
        nums = sorted(nums)
        min_num = nums[0] + nums[1] + nums[2]

        for i in range(l - 1):
            # 對於重複元素,跳過,避免重複計算(也可以不跳過)
            if i>0 and nums[i]==nums[i-1]:
                continue
            # 確定一個元素,左右指針調整,尋找最小值
            left, right = i + 1, l - 1
            while left < right:
                temp = nums[i] + nums[left] + nums[right]
                # temp=nums[i]+nums[Left]+nums[Right],如果temp=target,返回target
                if temp == target: return target
                # 若abs(temp-target)<abs(min_num-target)說明temp更接近目標,更新min_num
                if abs(temp - target) < abs(min_num - target):
                    min_num = temp
                # 若temp-target小於0,說明nums[Left]太小,Left右移
                if temp - target < 0:
                    while left<right and nums[left]==nums[left+1]: left+=1 # 加速跳過相同元素
                    left += 1
                # 若temp-target大於0,說明nums[Right]太大,Right左移
                else:
                    while left<right and nums[right]==nums[right-1]: right-=1
                    right -= 1
        return min_num

四數求和:

思路: 雙指針,2個外層循環,同時固定2個值,再左右指針遍歷

   def fourSum(self, nums, target) :
        l = len(nums)
        sum_nums = []
        if l < 4: return sum_nums
        sort_nums = sorted(nums)
        # 特例:[0,0,0,0] --- 0
        # if l == 4 and sort_nums[0]+sort_nums[1]+sort_nums[2]+sort_nums[3] ==target:
        #     sum_nums.append([sort_nums[0],sort_nums[1],sort_nums[2],sort_nums[3]])
        #     return sum_nums
        for i in range(l-3): # 第一個數字,全部遍歷
            if sort_nums[i]==sort_nums[i-1] :
                continue
            for j in range(i+1,l-2):
                left,right = j+1,l-1
                while left < right:
                    s = sort_nums[i] + sort_nums[j] + sort_nums[left] + sort_nums[right]
                    if s == target:
                        temp = [sort_nums[i] , sort_nums[j] , sort_nums[left] , sort_nums[right]]
                        sum_nums.append(temp)
                        while left < right and sort_nums[left] == sort_nums[left + 1]: left += 1
                        while left < right and sort_nums[right] == sort_nums[right - 1]: right -= 1
                        left +=1
                        right -=1
                    if s < target:
                        while left< right and sort_nums[left]==sort_nums[left+1]: left +=1
                        left +=1
                    elif s > target:
                        while left<right and sort_nums[right]==sort_nums[right-1]: right-=1
                        right -=1
        return sum_nums

 

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