917 字
5 分钟
代码随想录算法训练营第六天 | 哈希表 Part02
哈希表 Part02 笔记
454. 四数相加 II
class Solution: # 四数字相加问题可以转化为两个两数相加的问题 # 即将 nums1 和 nums2 的所有两数之和存入一个哈希表中,nums3 和 nums4 的所有两数之和则需要查找哈希表中是否存在对应的负数和 def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int: record = {} # 计算 nums1 和 nums2 的所有两数之和,并记录出现的次数 for num1 in nums1: for num2 in nums2: record[num1 + num2] = record.get(num1 + num2, 0) + 1
res = 0 # 对于 nums3 和 nums4 的每一对数字,计算它们的和,并查找哈希表中是否存在对应的负数和 for num3 in nums3: for num4 in nums4: need = 0 - (num3 + num4) if need in record: res += record[need] return res
383. 赎金信
class Solution: # 这个是和 LeetCode 242 有效的字母异位词 类似的题目 def canConstruct(self, ransomNote: str, magazine: str) -> bool: record = {} # 统计 magazine 中每个字母出现的次数 for char in magazine: record[char] = record.get(char, 0) + 1 # 遍历 ransomNote 中的每个字符,依次判断是否可以匹配 for char in ransomNote: if char in record and record[char] > 0: record[char] -= 1 else: return False return True
15. 三数之和
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() # 排序后方便使用双指针和去重 res = [] for i in range(len(nums) - 2): left = i + 1 right = len(nums) - 1 # 如果当前数字大于0,则后续的数字都大于0,无法满足三数之和为0 if nums[i] > 0: break # ⚠️ 注意这里需要跳过重复的数字,避免结果中出现重复的三元组 if i > 0 and nums[i] == nums[i - 1]: continue while left < right: total = nums[i] + nums[left] + nums[right] if total == 0: res.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 elif total < 0: left += 1 else: right -= 1 return res
18. 四数之和
class Solution: # 四数之和可以转化为三数之和的问题 # 首先对数组进行排序,然后固定前两个数字,使用双指针查找后两个数字 def fourSum(self, nums: List[int], target: int) -> List[List[int]]: nums.sort() # 排序以便使用双指针法 res = [] for i in range(len(nums) - 3): # 如果当前数字加上后三个最小的数字的和都大于目标值,则直接跳出循环 if nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target: break # 如果当前数字加上后三个最大的数字的和都小于目标值,则跳过当前数字 if nums[i] + nums[-1] + nums[-2] + nums[-3] < target: continue if i > 0 and nums[i] == nums[i - 1]: continue for j in range(i + 1, len(nums) - 2): # 如果当前数字加上后面两个最小的数字的和都大于目标值,则跳出循环 if nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target: break # 如果当前数字加上后面两个最大的数字的和都小于目标值,则跳过 if nums[i] + nums[j] + nums[-1] + nums[-2] < target: continue if j > i + 1 and nums[j] == nums[j - 1]: continue left = j + 1 right = len(nums) - 1 while left < right: total = nums[i] + nums[j] + nums[left] + nums[right] if total == target: res.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 total > target: right -= 1 else: left += 1 return res
代码随想录算法训练营第六天 | 哈希表 Part02
https://fuwari.vercel.app/posts/code_musings_day_six/