代码随想录第七天 || 1.四数相加|| 2.赎金信 3.三数之和

四数相加2: 

讲解:代码随想录

思路:

1.因为是四数之和,并且有四个数组,长度还相等,所以将四个数两个一组,计算和,简化为两数之和,前两个数的和放到哈希表中,因为要求四数之和为0,再求出后两个数的和,用0减去后可两个数的和,就是前两个数(因为前两个数加后两个数等于0,这是要求),此时只需要在前两个数之和的哈希表中找出有多少组等于这个值即可。

代码:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap = dict()
        for i in nums1:
            for j in nums2:
                if i+j in hashmap:
                    hashmap[i+j]+=1
                else:
                    hashmap[i+j]=1
        count=0
        for i in nums3:
            for j in nums4:
                cha = -i-j
                if cha in hashmap:#这种形式是检测键值是否在字典中,如果是检测值,那要在字典后加.values
                    count+=hashmap[cha]
        return count

遇到的问题:

1.没有搞清检测字典键和值的方法:如果是检测键那if cha in hashmap:如果是检测值那写成if cha in hashmap.values(): 后面的加上values()就相当于把字典的值都罗列了

 赎金信

讲解:代码随想录

思路:

创建两个数组哈希,因为只有字母,与之前的有效的字母异位词有几分相似,只不过这次,只用管magzine是否能组成ransomNote

代码:

使用数组:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        record1=[0]*26
        record2=[0]*26
        for i in ransomNote:
            record1[ord(i)-ord("a")]+=1
        for i in magazine:
            record2[ord(i)-ord("a")]+=1
        return all(record1[i]<=record2[i] for i in range(26))#重点   

遇到的问题:

1.对于python的简便写法

2.all()函数的使用:当其中所有情况为True,则返回True,否则为False

三数之和:

讲解:代码随想录

思路: 

1.哈希法:先排序,因为三个数在一个数组中所以,所以两层循环控制a,b,最后将符合条件的a和b的和放到哈希表中,寻找是否有符合条件的c,有则加到结果集中

2.双指针:先排序,先用一个循环控制a,再通过left和right指针在a到末尾的范围内找b和c

代码:

双指针法

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

哈希法:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        nums.sort()
        # 找出a + b + c = 0
        # a = nums[i], b = nums[j], c = -(a + b)
        for i in range(len(nums)):
            # 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i - 1]: #三元组元素a去重
                continue
            d = {}
            for j in range(i + 1, len(nums)):
                if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]: # 三元组元素b去重
                    continue
                c = 0 - (nums[i] + nums[j])
                if c in d:
                    result.append([nums[i], nums[j], c])
                    d.pop(c) # 三元组元素c去重
                else:
                    d[nums[j]] = j
        return result

遇到的问题:

1.哈希法中,为什么一定要用字典,因为字典的查询复杂度底,只有o(1),而如果使用列表则需要o(n^2)

2. if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]: # 三元组元素b去重  在这个哈希法的这一步去重,是为了特殊情况[0,0,0]很容易出错,所以推荐使用双指针法 

3.pop():字典的pop()里面是键值,列表的pop()里面是索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值