代码随想录算法训练营第7天|454. 四数相加 II,383. 赎金信, 15. 三数之和, 18. 四数之和

本文介绍了使用Python解决四数相加II和赎金信问题的算法。对于四数相加II,通过构建字典存储两两相加的结果,然后检查后两个数组的两两相加和是否存在于字典中。赎金信问题则利用计数器检查ransomNote中的字符是否都能在magazine中找到。此外,还讨论了三数之和及四数之和的双指针解法,强调了去重的细节处理。
摘要由CSDN通过智能技术生成

454. 四数相加 II

解题思路:

1. 将前两个数组两两相加,放入dictionary中的key,相加的和出现的次数放入value

2. 后两个数组也两两相加,判断相加和的负数是否出现再dictionary中

3. 如果在dictionary中,就将key对应得value加入输出的count中

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        dic = {}

        for a in nums1:
            for b in nums2:
                if a + b not in dic:
                    dic[a+b] = 1
                else:
                    dic[a+b] += 1
        
        count = 0
        for c in nums3:
            for d in nums4:
                key = -(c+d)
                if key in dic:
                    count += dic[key]
        return  count

383. 赎金信

解法1:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        # method 1
        ran = collections.Counter(ransomNote)

        for char in magazine:
            if char in ran:
                ran[char] -= 1
        
        for key in ran:
            if ran[key] > 0:
                return False
        return True

解法2:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
         # method 2
        ran = collections.Counter(ransomNote)
        mag = collections.Counter(magazine)

        diff = ran - mag

        if diff:
            return False
        else:
            return True

15. 三数之和

解法:双指针

解题思路:

1. a + b + c = 0

2. a 可以是当前数字

3.b可以是左指针(a的后一位数字)

4.c可以是右指针(数组的最后一个数字)

5.将这三个数字相加,得到三数之和,并且与0做比较

6. 大于0时,右指针向左退一个数字

7.小于0时,左指针向右进一个数字

8.等于时,放入输出结果中

细节注意:

1. 对于当前的数去重,是向前一位数做比较

2. 对于左指针去重,是与后面一位作比较

3.对于右指针去重,是与前面一位做比较

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        nums = sorted(nums)
        for i in range(len(nums)-2):
            if nums[i] > 0: break

            left = i + 1
            right = len(nums) -1 
            if i > 0 and nums[i] == nums[i-1]: continue

            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total == 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

                if total > 0:
                    right -= 1
                else:
                    left += 1
        return res

18. 四数之和

解法:双指针

细节注意:去重

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums = sorted(nums)
        res = []
        n = len(nums)
        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]: continue
            for j in range(i+1,n):
                if j > i+1 and nums[j] == nums[j-1]:continue

                left = j + 1
                right = n - 1

                while left < right:
                    total = nums[i] + nums[j] + nums[left] + nums[right]
                    if total == target:
                        res.append([nums[i],nums[j],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
                    if total > target:
                        right -= 1
                    else:
                        left += 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值