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

454:

本题主要是考虑如何将一个时间复杂度O(n^4)的算法降低时间复杂度,很容易想到直接4个for循环暴力计算,但其实本题既不关注4个元素在各自数组中的位置,也不关注其各自大小,题目只是需要最后的和满足某个条件即可,所以重点是“和”,以及满足这个“和”的组合有多少个,反正每个数组都得出一个元素,那就所以把4个数组揉在一起算,不如两两分组变成O(n^2)好了,用哈希法也是因为题目只关注“和是多少”,“有多少个”这两个信息,所以我们可以联想到python中字典两要素不正好是key和value嘛。所以我认为这道题顺着这个思路就自然出来了:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap={}
        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:
                value=-(i+j)
                if value in hashmap:
                    count+=hashmap[value]
        return count

那如果是5个数组呢?我想大概也可以用2个数组先构成一个hash表,然后再遍历另外两个数字来生成新的4元素相加的hash表,最后再由第五个数组来筛选和符合标准的个数,这样也能保证复杂度为O(n^2)

本题补充:

1.使用in即可检查元素(作为key)是否在字典dict或者集合set中,时间复杂度O(1)

2.dict和set在python就是使用哈希表实现的,所以在python中使用哈希法其实也某种程度就是说使用dict或者set来解决问题,dict比set多存储了一个value,所以需要根据实际情况来判断是否需要value,比如本题需要记录有多少个满足条件的组合,所以需要使用dict

383:

本题和434思路基本一致,是一道不错的拓展练习题

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        hashmap={}
        for s in magazine:
            if s in hashmap:
                hashmap[s]+=1
            else:
                hashmap[s]=1
        for s in ransomNote:
            if s in hashmap and hashmap[s]>0:
                hashmap[s]-=1
            else:
                return False
        return True

做完这题我想了下如果两个单词一样长呢,那是不是最后还要对字典进行一个遍历检查是否各项的value都是0?但是我突然意识到如果一样长不就退化成昨天的242了嘛,用一个长度为26的数组统计每个字母出现的次数即可,但是在这里还是需要再巩固下遍历字典的办法:

1.遍历所有 键(keys)

d = {'a': 1, 'b': 2, 'c': 3}

# 方法1:直接遍历字典(默认遍历 key)
for key in d:
    print(key)

# 方法2:显式调用 .keys()
for key in d.keys():
    print(key)

2.遍历所有 值(values)

for value in d.values():
    print(value)

3.遍历所有 键值对(key-value pairs)

# 使用 .items() 返回 (key, value) 元组
for key, value in d.items():
    print(f"{key}: {value}")

15:

本题和上面不同,本题是在同一个数组中处理,所以关注每个元素在该数组中的位置,如果使用哈希表来处理2个数据的和然后再和第三个元素比较,很容易出现第三个元素其实是前两个元素中其中一个的问题,防止重复使用一个元素所需要花费的代价比较大,所以不适合哈希法。但是又不允许返回的结果里有重复的相同的结果,所以在处理的时候,遇到相同元素时需要跳过,详见while循环处理。

并且这种一个数组里选择元素找和的,基本第一思路都是需要先排序,这里使用的sort函数是稳定的、时间复杂度O(n)~O(nlogn),是非常好用的一个排序函数了。

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 right>left and nums[right-1]==nums[right]:
                        right-=1
                    while right>left and nums[left]==nums[left+1]:
                        left+=1
                    right-=1
                    left+=1
        return result

至于一个数组中的4数相加,无非就是再嵌套一个for循环,然后注意对sum_判断以及nums[i]判断要根据target来,不能直接是0了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值