什么时候使用哈希法:
当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候
242.有效的字母异位词
解题思路
只有小写字母,想到可以用数组d,来记录字符串s里每个字符出现的次数,大小为26。
数组是一个简单的哈希表。使用数组来做哈希的题目,是因为题目都限制了数值的大小。如果没有限制数值的大小,就无法使用数组来做哈希表了。如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
把字符映射到数组的index上,从a到z的ascii number是26个连续的数值,所以a映射index是0, z是25。
遍历s,将d[ord(s[i]) - ord(‘a’) ] += 1
同时遍历t,检查t中是否出现了这些字符,将d[ord(t[i]) - ord(‘a’) ] -= 1
最后检查数组的数值, 如果有不为0的,说明不是anagram. 如果都为0,说明是。
遇到的问题
注意s[i] - ‘a’ 是两个string相减,会报错,要用ord: d[ord(s[i]) - ord(‘a’) ]
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
d = [0]*26
for i in range(len(s)):
d[ord(s[i]) - ord('a')] += 1
d[ord(t[i]) - ord('a')] -= 1
for char in d:
if char != 0:
return False
return True
时间复杂度 O(N)
空间复杂度 O(1) 是一个常量大小的辅助数组
349. 两个数组的交集
Intersection of Two Arrays - LeetCode
解题思路
直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。耗时在数据量大的情况,差距是很明显的。
数组都是 1000以内的。数组是一个简单的哈希表。使用数组来做哈希的题目,是因为题目都限制了数值的大小。如果没有限制数值的大小,就无法使用数组来做哈希表了。如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
定义一个数组a,大小为1001.
遍历nums1, a[num] = 1
遍历nums2,检查每个数字a[n] 的值是否等于1。如果等于1,放进res数组,并将a[n] == 0
return res
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# because nums length and value <= 1000, can use an array
a = [0] * 1001
res = []
for num in nums1:
a[num] = 1
for num in nums2:
if a[num] == 1:
res.append(num)
a[num] = 0
return res
时间复杂度 O(N)
空间复杂度 O(N)
202. 快乐数
解题思路
题目中说了会 无限循环,也就是说求和的过程中,和会重复出现,这对解题很重要!
当我们遇到了要快速判断一个元素是否出现在集合里的时候,就要考虑哈希法了。
使用set,来判断这个和是否重复出现,如果重复了就return false, otherwise一直找到和为1为止。
遇到的问题
难点是求和的部分怎么写
class Solution:
def isHappy(self, n: int) -> bool:
def getNext(n):
total = 0
while n > 0:
n, digit = divmod(n, 10)
total += digit **2
return total
s = set()
while n != 1 and n not in s:
s.add(n)
n = getNext(n)
return n == 1
时间复杂度 O(logN)
空间复杂度 O(logN)
1. 两数之和
解题思路
不仅要知道数组元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存index,所以选map。
遍历数组, 查询map里是否有和当前遍历数值匹配的数值(target -num):
如果有,即找到了匹配的pair
如果没有,用map存放访问过的元素
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = dict()
for idx, val in enumerate(nums):
diff = target - val
if diff not in d:
d[val] = idx
else:
return [idx,d[diff]]