今天的题普遍比较难,没想到曾经的hard题现在竟然降成了medium
454.四数相加II
这道题基本思路是参照2sum
Way1:
大体思路就是先合并前两个元素并用hashmap计数,然后合并后两个元素做查找
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
n3=[]
for x in nums1:
for y in nums2:
n3.append(x+y)
dic=Counter(n3)
res=0
for x in nums3:
for y in nums4:
key=-x-y
if key in dic:
res+=dic[key]
return res
383. 赎金信
这道题是昨天题的扩展
Way1:
大体思路就是建立两个hashmap,然后去比较值大小
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
dic1=Counter(ransomNote)
dic2=Counter(magazine)
for k,v in dic1.items():
if dic1[k]>dic2[k]:
return False
return True
15. 三数之和
这道题嘴最简单的方法是用two pointer,大致思路就是锚定第一个元素做遍历,根据值比大小来确定如何移动左右指针
Way1:
里面涉及到了对于锚定指针,左,右指针的优化
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
ans=[]
for i in range(len(nums)):
left=i+1
right=len(nums)-1
if nums[i]>0:
break
if i>=1 and nums[i]==nums[i-1]:
continue
while left<right:
total=nums[i]+nums[left]+nums[right]
if total>0:
right-=1
elif total<0:
left+=1
else:
ans.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
left += 1
right -= 1
return ans
18. 四数之和
本质上和上一题相同
Way1:
就是在上一题的基础上对第二个锚定指针也做优化
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
res=[]
for i in range(len(nums)):
if i>=1 and nums[i]==nums[i-1]:
continue
for j in range(i+1,len(nums)):
if j>i+1 and nums[j]==nums[j-1]:
continue
p=j+1
q=len(nums)-1
while p<q:
total=nums[i]+nums[j]+nums[p]+nums[q]
if total>target:
q-=1
elif total<target:
p+=1
else:
res.append([nums[i],nums[j],nums[p],nums[q]])
while p<q and nums[p]==nums[p+1]:
p+=1
while p<q and nums[q]==nums[q-1]:
q-=1
p += 1
q -= 1
return res
总结:
每当涉及到元素的查找时,就要考了用hash table了.本质上这是一种用空间换时间的做法.常用的数据结构有三种,即array,set,和dictionary.