系列文章目录
代码随想录算法训练营第一天|数组理论基础,704. 二分查找,27. 移除元素
代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
代码随想录算法训练营第三天|链表理论基础,203.移除链表元素,707.设计链表,206.反转链表
代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II,总结
代码随想录算法训练营第五天|哈希表理论基础,242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和
文章目录
- 系列文章目录
- 454.四数相加II
- 383. 赎金信
- 15. 三数之和
- 18. 四数之和
- 总结
454.四数相加II
题目链接: 454.四数相加II
题目内容: 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:0 <= i, j, k, l < n;nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
视频讲解:学透哈希表,map使用有技巧!LeetCode:454.四数相加II
核心思路:
先遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到字典中,然后遍历大C和大D数组,统计0-(c+d) 在dict中出现的情况。
class Solution:def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:record=dict()for i in range(len(nums1)):for j in range(len(nums2)):record[nums1[i]+nums2[j]]=record.get(nums1[i]+nums2[j],0)+1count=0for i in range(len(nums3)):for j in range(len(nums4)):target=nums3[i]+nums4[j]if 0-target in record:count+=record[0-target]return count
383. 赎金信
题目链接: 383.赎金信
题目内容: 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。magazine 中的每个字符只能在 ransomNote 中使用一次
使用数组:
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:ransomNote_count=[0]*26magazine_count=[0]*26for i in ransomNote:ransomNote_count[ord(i)-ord('a')]+=1for i in magazine:magazine_count[ord(i)-ord('a')]+=1return all(ransomNote_count[i]<=magazine_count[i] for i in range(26))
使用字典:
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:record={}for i in magazine:record[i]=record.get(i,0)+1for i in ransomNote:if i not in record or record[i] == 0:return Falserecord[i]-=1return True
15. 三数之和
题目链接: 15.三数之和
题目内容: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
视频讲解:梦破碎的地方!| LeetCode:15.三数之和
哈希法:
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:result = []nums.sort()# 找出a + b + c = 0# a = nums[i], b = nums[j], c = -(a + b)for i in range(len(nums)):# 排序之后如果第一个元素已经大于零,那么不可能凑成三元组if nums[i] > 0:breakif i > 0 and nums[i] == nums[i - 1]: #三元组元素a去重continued = {}for j in range(i + 1, len(nums)):if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]: # 三元组元素b去重continuec = 0 - (nums[i] + nums[j])if c in d:result.append([nums[i], nums[j], c])d.pop(c) # 三元组元素c去重else:d[nums[j]] = jreturn result
双指针法:
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums.sort()result=[]for i in range(len(nums)):if nums[i] > 0: return resultif i > 0 and nums[i] == nums[i-1]:continueleft=i+1right=len(nums)-1while left<right:if nums[left]+nums[right]+nums[i]>0:right-=1elif nums[left]+nums[right]+nums[i]<0:left+=1else:result.append([nums[i],nums[left],nums[right]])while right>left and nums[right]==nums[right-1]:right-=1while right>left and nums[left]==nums[left+1]:left+=1left+=1right-=1return result
18. 四数之和
题目链接: 18.四数之和
题目内容: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0 <= a, b, c, d < n;a、b、c 和 d 互不相同;nums[a] + nums[b] + nums[c] + nums[d] == target;你可以按 任意顺序 返回答案 。
视频讲解:难在去重和剪枝!| LeetCode:18. 四数之和
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:# 剪枝(可省)breakif i > 0 and nums[i] == nums[i-1]:# 去重continuefor j in range(i+1, n):if nums[i] + nums[j] > target and target > 0: #剪枝(可省)breakif j > i+1 and nums[j] == nums[j-1]: # 去重continueleft, right = j+1, n-1while 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 += 1while left < right and nums[right] == nums[right-1]:right -= 1left += 1right -= 1elif s < target:left += 1else:right -= 1return result
总结
- 一般来说哈希表都是用来快速判断一个元素是否出现集合里;
- 使用哈希法解决问题时,一般会选择如下三种数据结构:数组、set (集合)、map(映射):
- 数组:哈希值比较小,范围也比较小
- set:数值比较大
- map:key,value