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了
973

被折叠的 条评论
为什么被折叠?



