训练营Day07 | 哈希表2

64 阅读1分钟

454. 四数相加 II

将数组分成两两配对

def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
    from collections import defaultdict
    sum_12 = defaultdict(int)
    sum_34 = defaultdict(int)
    n = len(nums1)
    res = 0
    for i in range(n):
        for j in range(n):
            sum_12[nums1[i]+nums2[j]] += 1
            sum_34[nums3[i]+nums4[j]] += 1

    for k in sum_12.keys():
        if -k in sum_34.keys():
            res += sum_12[k] * sum_34[-k]
    
    return res

383. 赎金信

def canConstruct(self, ransomNote: str, magazine: str) -> bool:

    word_r = [0] * 26
    word_m = [0] * 26

    for r in ransomNote:
        word_r[ord(r) - ord("a")] += 1
    for m in magazine:
        word_m[ord(m) - ord("a")] += 1

    for i in range(26):
        if word_m[i] < word_r[i]:
            return False
    
    return True

15. 三数之和

遍历+双指针

两数之和 不能使用双指针法,因为 两数之和 要求返回的是索引下标, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。

def threeSum(self, nums: List[int]) -> List[List[int]]:
    nums.sort()
    res = []

    # double pointers
    
    for i in range(len(nums)-2):
        if nums[i] > 0: 
            break

        start = i + 1
        end = len(nums) - 1

        while start < end:

            if nums[i] + nums[start] + nums[end] < 0:
                while start < end and nums[i] + nums[start] + nums[end] < 0:
                    start += 1
            elif nums[i] + nums[start] + nums[end] > 0:
                while start < end and nums[i] + nums[start] + nums[end] > 0:
                    end -= 1
            
            if nums[i] + nums[start] + nums[end] == 0 and start != end:
                if [nums[i], nums[start], nums[end]] not in res:
                    res.append([nums[i], nums[start], nums[end]])
                start += 1
                end -= 1

    return res

更好的去重方式:

剪枝

18. 四数之和

类三数之和,但由于范围是target可能小于0,因此无法提前判断

def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
    
    nums.sort()
    res = []

    n = len(nums)

    for i in range(n-3):

        for j in range(i+1, n-2):

            start = j + 1
            end = n - 1
            while start < end:
                if nums[i] + nums[j] + nums[start] + nums[end] > target:
                    # while start < end and nums[i] + nums[j] + nums[start] + nums[end] > target:
                        end -= 1
                elif nums[i] + nums[j] + nums[start] + nums[end] < target:
                    # while start < end and nums[i] + nums[j] + nums[start] + nums[end] > target:
                        start += 1
                if nums[i] + nums[j] + nums[start] + nums[end] == target and start != end:
                    if [nums[i], nums[j], nums[start], nums[end]] not in res:
                        res.append([nums[i], nums[j], nums[start], nums[end]])
                    end -= 1
                    start += 1
    
    return res