Leetcode 刷题记录 Day5
哈希表数组理论
哈希表: 哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素, 其实数组就是一个哈希表。哈希表通常用于快速判断某个元素是否在表中, O(1)。
哈希函数(hash function):ex. 找学生名字是否在学校中哈希函数。Hash Function把学生的姓名直接映射为哈希表上的索引,然后就可以通过查询索引下标快速知道这位同学是否在这所学校里了。
如果hashCode得到的数值大于 哈希表的大小了,也就是大于tableSize了,怎么办呢?
此时为了保证映射出来的索引数值都落在哈希表上,我们会在再次对数值做一个取模的操作,这样我们就保证了学生姓名一定可以映射到哈希表上了。
哈希碰撞:
拉链法:
线性探索法:
常见哈希结构:
- list
- set
- map/dictionary
总结: 当我们需要快速寻找一个目标是否在集合中, 就要考虑哈希表
242. Valid Anagram
目标: 判断是否由相同字符构成
哈希法解题: 三种常见哈希表(数组, set, map)
a - z, 总共26个小写字符, 利用ASCII码 由于是连续的a对应到0,b对应到1, etc.
利用 ord('x') - ord('a')得到x的order;
定义数组长度为26, 用于记录第一个数组每个字符出现哦频率, 第二个数组进行扣减, 最后数组都为0则True
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0] * 26
for i in s:
record[ord(i) - ord('a')] = record[ord(i)- ord('a')] + 1
for j in t:
record[ord(j)- ord('a')] = record[ord(j)- ord('a')] - 1
for r in range(26):
if record[r] != 0:
return False
return True
349. Intersection of Two Arrays
为什么用哈希表? 哈希表擅长于解决判断元素是否在集合中出现
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 使用dictionary解决
hash = {}
for n1 in nums1:
hash[n1] = hash.get(n1, 0) + 1
res = []
for n2 in nums2:
if n2 in hash:
res.append(n2)
del hash[n2]
return res
202. Happy Number
重点是: 如果不是Happy Number, 会无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
class Solution:
def isHappy(self, n: int) -> bool:
def get_sum(n):
s = 0
for i in str(n):
s += int(i) ** 2
return s
hash = set()
while True:
n = get_sum(n)
if n == 1:
return True
if n in hash:
return False
hash.add(n)
1. Two Sum
使用Hash表是因为在遍历这个list时, 寻找是否已经遇过这个值, hash表中存储这个值以及对应index。使用dictionary, key是值, value是index
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
record = {}
for i, n in enumerate(nums):
if target - n in record:
return [record[target - n], i]
record[n] = i
454. Four Sums II
四个元素中各选一个加起来为0的组合有多少(不去重)
为什么用哈希表? 将所有nums1, nums2的组合计入hash map, 然后判断nums3 nums4里的元素和是否有-num1-nums2的元素, 讲count加起来。使得时间复杂度为O(n^2)
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
hash = {}
for n1 in nums1:
for n2 in nums2:
hash[n1 + n2] = hash.get(n1 + n2, 0) + 1
count = 0
for n3 in nums3:
for n4 in nums4:
if -n3 - n4 in hash:
count += hash[-n3 - n4]
return count
383. Ransom Note
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
word_count = [0] * 26
for s in magazine:
word_count[ord(s) - ord('a')] += 1
for r in ransomNote:
if word_count[ord(r) - ord('a')] >= 1:
word_count[ord(r) - ord('a')] -= 1
else:
return False
return True
15. 3Sum
哈希法去重操作过于复杂
使用三指针法:
先排序
i遍历0 -> len(nums) - 3的位置, left初始为i + 1, right为len(nums) - 1
如何更新left, right?和大于0 缩小right, 小于0 增加left, 等于0 记入result并同时更新left, right
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
def move_left(nums, l, r):
while r > l and nums[l] == nums[l + 1]:
l += 1
l += 1
return l
def move_right(nums, l, r):
while r > l and nums[r] == nums[r - 1]:
r -= 1
r -= 1
return r
res = []
nums.sort()
i = 0
while i < len(nums) - 2:
l, r = i + 1, len(nums) - 1
while l < r:
temp_sum = nums[i] + nums[l] + nums[r]
if temp_sum > 0:
r = move_right(nums, l, r)
elif temp_sum < 0:
l = move_left(nums, l, r)
else:
res.append([nums[i], nums[l], nums[r]])
r = move_right(nums, l, r)
l = move_left(nums, l, r)
while nums[i] == nums[i + 1] and i < len(nums) - 2:
i += 1
i += 1
return res
18. 4Sum
与上题方法一样, 双指针但多了一层循环
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
res = []
a = 0
while a < len(nums) - 3:
b = a + 1
while b < len(nums) - 2:
c = b + 1
d = len(nums) - 1
while c < d:
temp_sum = nums[a] + nums[b] + nums[c] + nums[d]
if temp_sum < target:
c += 1
while c < d and nums[c] == nums[c - 1]:
c += 1
elif temp_sum > target:
d -= 1
while c < d and nums[d] == nums[d + 1]:
d -= 1
else:
res.append([nums[a], nums[b], nums[c], nums[d]])
c += 1
while c < d and nums[c] == nums[c - 1]:
c += 1
d -= 1
while c < d and nums[d] == nums[d + 1]:
d -= 1
b += 1
while b < len(nums) - 2 and nums[b] == nums[b - 1]:
b += 1
a += 1
while a < len(nums) - 3 and nums[a] == nums[a - 1]:
a += 1
return res
好累😫