刷题Day(6) | 代码随想录

66 阅读2分钟

本系列文章是我刷代码随想录过程中的笔记。代码地址:leetcode

今天是我刷“代码随想录”的第六天

今日内容

  • 454.四数相加II
  • 383.赎金信
  • 15.三数之和
  • 18.四数之和
  • 总结

leetcode 454. 四数相加 II

这道我们两两分组,先计算nums1与nums2的和,并使用dict记录,然后再nums3和nums4中判断是否出现过。如果出现过,记录的次数就加上nums1与nums2的和出现的次数。

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        dic = dict()
        count = 0
        for i in nums1:
            for j in nums2:
                s = i + j
                if s in dic:
                    dic[s] += 1
                else:
                    dic[s] = 1

        for i in nums3:
            for j in nums4:
                s = 0 - i - j
                if s in dic:
                    count += dic[s]
        return count

leetcode 383. 赎金信

这道题与昨天的异位字符串相同,先记录下两个字符串中字符出现的个数。然后遍历较短的字符串生成的shortDict,当在longDict中找不到短的字母或者出现的次数小于短的个数时,说明无法构成该短的字符串,返回false。

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        shortDic = dict()
        longDic = dict()
        for i in ransomNote:
            if i in shortDic:
                shortDic[i] += 1
                continue
            shortDic[i] = 1
        for i in magazine:
            if i in longDic:
                longDic[i] += 1
                continue
            longDic[i] = 1
        for k, v in shortDic.items():
            if k not in longDic or v > longDic[k]:
                return False
        return True

leetcode 15. 三数之和

这道题的难点在于如何去重。首先使用for循环固定一个值nums[i],然后对剩余的元素使用双指针法。

  • 注意点一:如果nums[i] > 0的话,剩下的元素不会再比0小了,这时候可以直接返回result
  • 注意点二:如果碰到两个连续元相同,那么需要去重,即直接跳过。

再往结果中添加元素的时候,注意如果左右指针也存在相同的元素,也需要跳过。以保证结果的唯一性。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        result = []
        for i in range(n):
            if nums[i] > 0:
                return result
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            left = i + 1
            right = n - 1
            while left < right:
                s = nums[i] + nums[left] + nums[right]
                if s >0 :
                    right -= 1
                if s < 0:
                    left += 1
                if s == 0:
                    result.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 += 1
                    right -= 1
        return result

leetcode 18. 四数之和

这道题与三数之和一样,但是需要固定两个值,去重两次。

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        result = []
        for i in range(n):
            if i > 0 and  nums[i] == nums[i - 1] : continue # 对i去重
            for j in range(i + 1, n):
                if j > i + 1 and nums[j] == nums[j - 1]: continue # 对j去重
                l = j + 1
                r = n - 1
                while l < r:
                    s = nums[i] + nums[j] + nums[l] + nums[r]
                    if s > target:
                        r -= 1
                    if s < target:
                        l += 1
                    if s == target:
                        result.append([nums[i], nums[j],nums[l], nums[r]])
                        while l < r and nums[l] == nums[l + 1]:l += 1
                        while l < r and nums[r] == nums[r - 1]:r -= 1
                        l += 1
                        r -= 1
        return result

总结

今天是哈希表的最后一天。哈希表的题主要是思路不好想。如果想到了,那么基本上就是秒杀。我在这方面的思路还比较欠缺。需要进一步的练习。