day 6 | 继续哈希表

文章讲述了如何使用排列、双指针技巧以及collections.Counter数据结构来解决四数之和问题(如18题),同时介绍了如何用Counter检查字符组合是否满足构造要求(如383题)。
摘要由CSDN通过智能技术生成

目录​​​​​​​

​​​​​​​18 四数之和

题目描述:

题解:排列➕双指针(借助三数之和)

454 四数相加2

题目描述:

题解一:

题解二:collections.Counter

383 赎金信

题目描述:

题解一:

题解二:collections.Counter


18 四数之和

题目描述:

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

题解:排列➕双指针(借助三数之和)

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        l = len(nums)
        ans = []
        #for i in range(l-2):不对
        for i in range(l-3):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            if nums[i] > target / 4:
                break
            cur_target = target - nums[i]
            #sub_nums = nums[i:] 不对
            sub_nums = nums[i + 1:]
            for sub_ans in self.threeSum(sub_nums, cur_target, l - i - 1):
                #不能这样写
                # cur_ans = sub_ans.append(nums[i])
                cur_ans = [nums[i]] + sub_ans
                ans.append(cur_ans)
        return ans
    
    def threeSum(self, nums, target, l):
        ans = []
        for i in range(l-2):
            #注意
            if i > 0 and nums[i] == nums[i-1]:
                continue
            slow = i + 1
            fast = l - 1

            #注意
            while slow < fast:
                cur_sum = nums[i] + nums[slow] + nums[fast]
                if cur_sum < target:
                    slow += 1
                elif cur_sum > target:
                    fast -= 1
                else:
                    ans.append([nums[i], nums[slow], nums[fast]])
                    while slow < fast and nums[slow] == nums[slow+1]:
                        slow += 1
                    while slow < fast and nums[fast] == nums[fast-1]:
                        fast -= 1
                    slow += 1
                    fast -= 1
        return ans

454 四数相加2

题目描述:

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

题解一:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        sum12_map = {}
        ans = 0
        for i, a in enumerate(nums1):
            for j, b in enumerate(nums2):
                cur_sum = str(a + b)
                if cur_sum in sum12_map.keys():
                    sum12_map[cur_sum] += 1
                else:
                    sum12_map[cur_sum] = 1
        for i, a in enumerate(nums3):
            for j, b in enumerate(nums4):
                cur_sum = str(- (a + b))
                if cur_sum in sum12_map.keys():
                    ans += sum12_map[cur_sum]
        return ans

题解二:collections.Counter

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        #sum12_map = {}
        ans = 0
        # for i, a in enumerate(nums1):
        #     for j, b in enumerate(nums2):
        #         cur_sum = str(a + b)
        #         if cur_sum in sum12_map.keys():
        #             sum12_map[cur_sum] += 1
        #         else:
        #             sum12_map[cur_sum] = 1
        sum12_map = collections.Counter(u + v for u in nums1 for v in nums2)
        for i, a in enumerate(nums3):
            for j, b in enumerate(nums4):
                cur_sum = - (a + b)
                # cur_sum = str(- (a + b))
                # if cur_sum in sum12_map.keys():
                if cur_sum in sum12_map:
                    ans += sum12_map[cur_sum]
        return ans

383 赎金信

题目描述:

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

题解一:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        magazine_dict = {}
        for _, e in enumerate(magazine):
            if e in magazine_dict.keys():
                magazine_dict[e] += 1
            else:
                magazine_dict[e] = 1
        for i, e in enumerate(ransomNote):
            if e not in magazine:
                return False
            elif magazine_dict[e] == 0:
                return False
            else:
                magazine_dict[e] -= 1
        return True

题解二:collections.Counter

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        if len(ransomNote) > len(magazine):
            return False
        # 在 collections.Counter 中,相减运算指的是两个计数器对象之间的减法操作。这个操作会计算两个计数器中各个元素的差异。
        # 具体来说,假设有两个 Counter 对象 counter1 和 counter2,它们分别表示不同元素的计数情况。当执行 counter1 - counter2 时,将对两个计数器对象进行减法运算,得到一个新的 Counter 对象。
        # 减法运算会对每个元素的计数进行操作:
        # 如果某个元素在 counter1 中的计数大于等于在 counter2 中的计数,则在结果 Counter 对象中该元素的计数为两者之差。
        # 如果某个元素在 counter1 中的计数小于在 counter2 中的计数,或者该元素在 counter1 中不存在,则在结果 Counter 对象中该元素的计数为 0。
        return not collections.Counter(ransomNote) - collections.Counter(magazine)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值