讲解
● 454.四数相加II
● 383. 赎金信
● 15. 三数之和
● 18. 四数之和
● 总结
题目链接:454. 四数相加 II
- 两两遍历
- 将前两个数组的和存到map中(字典)
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
dic1 = {}
count = 0
for i in range(len(nums1)):
for j in range(len(nums2)):
sum1 = nums1[i]+nums2[j]
if sum1 not in dic1.keys():
dic1[sum1] = 1
else:
dic1[sum1] += 1
for k in range(len(nums3)):
for l in range(len(nums4)):
target = 0 - (nums3[k] + nums4[l])
if target in dic1.keys():
count += dic1[target]
return count
- 时间复杂度: O(n^2)
- 空间复杂度: O(n^2),最坏情况下A和B的值各不相同,相加产生的数字个数为 n^2
题目链接:383. 赎金信
- 使用哈希表(与242.有效字母异位词相似)
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
ht = [0] * 26
for c in magazine:
ht[ord(c) - ord("a")] += 1
for m in ransomNote:
ht[ord(m) - ord("a")] -= 1
for i in ht:
if i < 0 :
return False
return True
题目链接:15. 三数之和
- 先给数组排序
- 使用左右双指针
- 指针在数组右边移动
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
lens = len(nums)
result = []
nums.sort() #对数组进行排序
i = 0
while(i < lens):
while(i > 0 and (nums[i] == nums[i-1]) and i < lens-1): #第一个数去重
i += 1
if nums[i] <= 0: #当nums[i]>0,说明右边的数都大于0,和不可能等于0
left = i + 1 #左指针
right = lens - 1 #右指针
while(left < right):
if nums[i] + nums[left] + nums[right] < 0: #和小于0,需要增大,左指针右移
left += 1
elif nums[i] + (nums[left] + nums[right]) > 0:#和大于0,需要减小,右指针左移
right -= 1
else:
result.append([nums[i],nums[left],nums[right]]) #存值
while(left < right): #左右指针数组值去重
if(nums[left] == nums[left+1]):
left += 1
elif(nums[right] == nums[right-1]):
right -= 1
else:
break
left += 1
right -= 1
i += 1
return result
题目链接:18. 四数之和
未看讲解时写的:
- 先给数组排序
- 使用左右双指针
- 指针在数组中间移动
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
lens = len(nums)
i = 0
j = lens-1
result = []
while(i+2<j):
while(i+2<j):
while(i<j and j<lens-1 and nums[j] == nums[j+1]):
j -= 1
while(i>0 and i<j and nums[i] == nums[i-1]):
i += 1
if(i+2<j):
left = i+1
right = j-1
while(left<right):
if(nums[i]+nums[j]+nums[left]+nums[right] > target):
right -= 1
elif(nums[i]+nums[j]+nums[left]+nums[right] < target):
left += 1
else:
result.append([nums[i],nums[left],nums[right],nums[j]])
while(left<right):
if nums[right] == nums[right-1]:
right -= 1
elif nums[left] == nums[left+1]:
left += 1
else:
break
right -= 1
left += 1
i += 1
i = 0
j -= 1
return result
看完讲解后写的:
- 先给数组排序
- 使用双指针
- 指针在右边移动
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
result = []
for i in range(len(nums)):
if nums[0] > target and target > 0:
break
if i > 0 and nums[i] == nums[i-1]:
continue
for j in range(i+1,len(nums)):
sum1 = nums[i]+nums[j]
if sum1 > target and target>0:
break
if j>i+1 and nums[j] == nums[j-1]:
continue
left = j + 1
right = len(nums) - 1
while left < right:
if sum1 + nums[left] + nums[right] > target:
right -= 1
elif sum1 + nums[left] + nums[right] < target:
left += 1
else:
result.append([nums[i],nums[j],nums[left],nums[right]])
while(left<right):
if nums[left] == nums[left+1]:
left += 1
elif nums[right] == nums[right-1]:
right -= 1
else:
break
left += 1
right -= 1
return result