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

1)文章链接:

[454]四数相加II

[383]赎金信

[15]三数之和

[18]四数之和

2)视频链接:

 学透哈希表,map使用有技巧!LeetCode:454.四数相加II_哔哩哔哩_bilibili

梦破碎的地方!| LeetCode:15.三数之和_哔哩哔哩_bilibili

难在去重和剪枝!| LeetCode:18. 四数之和_哔哩哔哩_bilibili

3)今日收获:a.四数相加II将四个数组分成两组分别计算,第二组的判断就转化成了hash表能解决的问题(“当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了”)  b.三数之和/四数之和有3点需要注意,分别是排序、剪枝、去重 

[454]四数相加II


1.题目链接:https://leetcode.cn/problems/4sum-ii/

2.题目难度:Medium

3.主要思路:a. 返回的是元组的个数 b.分成两个组,两两为一组 c.用dic的key-value存储第一组的和,以及和出现的次数; 然后计算并判断第二组的和的反数是否在第一组的dic结果中出现

4.代码:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        dic = {}
        len_ = len(nums1)
        for i in range(len_):
            for j in range(len_):
                a = nums1[i]+nums2[j]
                dic[a] = dic.get(a,0)+1
        res = 0
        for i in range(len_):
            for j in range(len_):
                b = nums3[i]+nums4[j]
                if -b in dic.keys():
                    res+=dic[-b]
        return res

[383]赎金信


1.题目链接:https://leetcode.cn/problems/ransom-note/

2.题目难度:Easy

3.主要思路:因为题目中提到所有的字母均为小写字母,解答方式同 [242]有效的字母异位词,见代码随想录算法训练营第六天|242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和_Mengting_OUYANG的博客-CSDN博客

4.代码:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        res = [0]*26
        for i in range(len(magazine)):
            res[ord(magazine[i])-ord('a')] +=1
        for j in range(len(ransomNote)):
            res[ord(ransomNote[j])-ord('a')]-=1
        for k in range(len(res)):
            if res[k]<0:
                return False
        return True

[15]三数之和


1.题目链接:https://leetcode.cn/problems/3sum/

2.题目难度:Medium

3.主要思路:a. 排序 b.剪枝 c.去重 d.注意当满足条件等于0后双指针需要继续移动

4.代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res = []
        for i in range(len(nums)-2):
            if nums[i]>0: # 剪枝
                return res
            if i>0 and nums[i]==nums[i-1]: #去重
                continue
            j = i+1
            k = len(nums)-1
            while j<k:
                a = nums[i]+nums[j]+nums[k]
                if a==0:
                    res.append([nums[i],nums[j],nums[k]])
                    while j<k and nums[j+1]==nums[j]:
                        j+=1
                    while j<k and nums[k-1]==nums[k]:
                        k-=1
                    j+=1
                    k-=1
                elif a>0:
                    while j<k and nums[k-1]==nums[k]:
                        k-=1
                    k-=1
                else:
                    while j<k and nums[j+1]==nums[j]:
                        j+=1
                    j+=1
        return res

[18]四数之和


1.题目链接:https://leetcode.cn/problems/4sum/

2.题目难度:Medium

3.主要思路:a. 排序 b.剪枝 c.去重 d.等价于在三数之和外面多包了一层,[b/c]双层两次操作, 注意这里的target可以是负数/正数/0.

4.代码:

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        def threeSum(nums, target):
            nums.sort()
            res = []
            for i in range(len(nums)-2):
                if nums[i]>target and nums[i]>0: # 剪枝
                    return res
                if i>0 and nums[i]==nums[i-1]: #去重
                    continue
                j = i+1
                k = len(nums)-1
                while j<k:
                    a = nums[i]+nums[j]+nums[k]
                    if a==target:
                        res.append([nums[i], nums[j], nums[k]])
                        while j<k and nums[j+1]==nums[j]:
                            j+=1
                        while j<k and nums[k-1]==nums[k]:
                            k-=1
                        j+=1
                        k-=1
                    elif a>target:
                        while j<k and nums[k-1]==nums[k]:
                            k-=1
                        k-=1
                    elif a<target:
                        while j<k and nums[j+1]==nums[j]:
                            j+=1
                        j+=1
            return res

        # 四数之和最外层循环
        res = []
        nums.sort()
        for i in range(len(nums)-3):
            if nums[i]>target and nums[i]>0: # 最外层的剪枝
                return res
            if i>0 and nums[i]==nums[i-1]: #最外层的去重
                continue
            a = [[nums[i]]+_ for _ in threeSum(nums[i+1:], target-nums[i])]
            res.extend(a)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值