一、四数相加二
'''
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/4sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
'''
#导包,defaultdict函数
from collections import defaultdict
class Solution:
def fourSumCount(self, nums1: list[int], nums2: list[int], nums3: list[int], nums4: list[int]) -> int:
#定义一个字典
temp = defaultdict(int)
#定义count初始化为0,用于记录符合要求的组合数
count = 0
#两层遍历,将n1+n2存入字典的key中,对应的value为key出现的次数
for n1 in nums1:
for n2 in nums2:
temp[n1 + n2] += 1
#两层遍历,将n3+n4的相反数赋值给key,如果key在前述字典中的key中,count就可以加key对应的value
for n3 in nums3:
for n4 in nums4:
key = -(n3 + n4)
if key in temp.keys():
count += temp[key]
return count
二、赎金信
'''
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ransom-note
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
'''
class Solution:
#本解法利用字典的特性来求解
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
result = {}
#将magazine字符串中的元素作为key存入字典中
for i in magazine:
if i in result.keys():
result[i] += 1
else:
result[i] = 1
#遍历信中的元素
for j in ransomNote:
# 当j不在字典的key中时,说明没有需要的字母,返回false
if j not in result.keys():
return False
#当j在字典的key中时,key对应的value减一
else:
result[j] -= 1
for value in result.values():
#前序遍历结束后,如果有value小于0时,说明该字母数量少于需求,返回false
if value < 0:
return False
#前序遍历全部结束,即可返回true
return True
三、三数之和
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
result = []
nums.sort()
# 此题去重不能用set,因为不是对元素去重,是对三元组去重,所以要对三元组中的每个元素分别去重
for i in range(len(nums)):
# 如果第一个元素已经大于0,不需要进一步检查
if nums[i] > 0:
return result
# 跳过相同的元素以避免重复
# if i > 0 and nums[i] == nums[i + 1] 此为错误去重方法,
if i > 0 and nums[i] == nums[i - 1]:
continue
# 左右双指针
left = i + 1
right = len(nums) - 1
# 左右指针不能相等,相等时指向同一位置
while right > left:
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] == nums[right - 1]:
right -= 1
while right > left and nums[left] == nums[left + 1]:
left += 1
right -= 1
left += 1
return result
四、四数之和
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n = len(nums)
result = []
for i in range(n):
if nums[i] > target and nums[i] > 0 and target > 0:# 剪枝(可省)
break
if i > 0 and nums[i] == nums[i-1]:# 去重
continue
for j in range(i+1, n):
if nums[i] + nums[j] > target and target > 0: #剪枝(可省)
break
if j > i+1 and nums[j] == nums[j-1]: # 去重
continue
left, right = j+1, n-1
while left < right:
s = nums[i] + nums[j] + nums[left] + nums[right]
if s == target:
result.append([nums[i], nums[j], 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
elif s < target:
left += 1
else:
right -= 1
return result
贵在坚持 day07