Day 7| 454.四数相加II 、383. 赎金信 、15. 三数之和 、18. 四数之和
454.四数相加II
建议:本题是 使用map 巧妙解决的问题,好好体会一下 哈希法 如何提高程序执行效率,降低时间复杂度,当然使用哈希法 会提高空间复杂度,但一般来说我们都是舍空间 换时间, 工业开发也是这样。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0454.四数相加II.html
思考
4个独立的数组,可以用哈希解决。
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
sum_dic = {}
for i in nums1:
for j in nums2:
if i+j not in sum_dic:
sum_dic[i+j]=1
else:
sum_dic[i+j]+=1
res = 0
for i in nums3:
for j in nums4:
if -(i+j) in sum_dic:
res+=sum_dic[-i-j]
return res
383. 赎金信
建议:本题 和 242.有效的字母异位词 是一个思路 ,算是拓展题
题目链接/文章讲解:https://programmercarl.com/0383.赎金信.html
思考
很简单的一道题
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
char_map = [0] * 26
for c in magazine:
char_map[ord(c)-ord('a')]+=1
for c in ransomNote:
if char_map[ord(c)-ord('a')] <= 0:
return False
char_map[ord(c)-ord('a')]-=1
return True
15. 三数之和
建议:本题虽然和 两数之和 很像,也能用哈希法,但用哈希法会很麻烦,双指针法才是正解,可以先看视频理解一下 双指针法的思路,文章中讲解的,没问题 哈希法很麻烦。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0015.三数之和.html
思考
双指针的题目,二刷了,还是卡了一点时间,而且代码去重还没做好,需要剪枝。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
n = len(nums)
res=[]
for i in range(n-2):
if i > 0 and nums[i] == nums[i-1]:
continue
left = i+1
right = n-1
while left<right:
if nums[i] + nums[left] + nums[right] == 0:
res.append([nums[i] , nums[left] , nums[right]])
temp = nums[left]
left+=1
while nums[left] == temp and left<right:
left+=1
elif nums[i] + nums[left] + nums[right] < 0:
left+=1
else:
right-=1
return res
优化去重逻辑,bc都要去重。另外,要进行剪枝。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
n = len(nums)
res=[]
for i in range(n-2):
if nums[i] > 0:
return res
if i > 0 and nums[i] == nums[i-1]:
continue
left = i+1
right = n-1
while left<right:
if nums[i] + nums[left] + nums[right] == 0:
res.append([nums[i] , nums[left] , nums[right]])
while left<right and nums[left] == nums[left+1] :
left+=1
left+=1
while left<right and nums[right] == nums[right-1]:
right-=1
right-=1
elif nums[i] + nums[left] + nums[right] < 0:
left+=1
else:
right-=1
return res
18. 四数之和
建议: 要比较一下,本题和 454.四数相加II 的区别,为什么 454.四数相加II 会简单很多,这个想明白了,对本题理解就深刻了。 本题 思路整体和 三数之和一样的,都是双指针,但写的时候 有很多小细节,需要注意,建议先看视频。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0018.四数之和.html
思考
解法上和三数之和一样的,多了一层循环,先写一个去重版本的。
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n = len(nums)
res = []
for i in range(n-3):
if i>0 and nums[i]==nums[i-1]:
continue
for j in range(i+1,n-2):
if j > i+1 and nums[j]==nums[j-1]:
continue
left = j+1
right = n-1
while left<right:
sum_ = nums[i]+nums[j]+nums[left]+nums[right]
if sum_ == target:
res.append([nums[i] ,nums[j], nums[left] , nums[right]])
while left<right and nums[left] == nums[left+1] :
left+=1
left+=1
while left<right and nums[right] == nums[right-1]:
right-=1
right-=1
elif sum_ < target:
left+=1
else:
right-=1
return res
剪枝优化版本,只有nums[i] > target and nums[i] >= 0 才可以
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n = len(nums)
res = []
for i in range(n-3):
if i>0 and nums[i]==nums[i-1]:
continue
if nums[i] > target and nums[i] >= 0:
return res
for j in range(i+1,n-2):
if j > i+1 and nums[j]==nums[j-1]:
continue
if nums[i] + nums[j] > target and nums[i] + nums[j] >= 0:
break
left = j+1
right = n-1
while left<right:
sum_ = nums[i]+nums[j]+nums[left]+nums[right]
if sum_ == target:
res.append([nums[i] ,nums[j], nums[left] , nums[right]])
while left<right and nums[left] == nums[left+1] :
left+=1
left+=1
while left<right and nums[right] == nums[right-1]:
right-=1
right-=1
elif sum_ < target:
left+=1
else:
right-=1
return res
浙公网安备 33010602011771号