四数相加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()里面是索引