Day06 哈希表
1. 哈希表理论基础
遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法
要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1)就可以做到。
1.1. 哈希函数
通过哈希函数将数值映射到对应的索引,通过索引快速查找
1.2. 哈希碰撞
在使用哈希函数映射时可能出现将不同数值映射到同一个索引下的情况(数值量大于哈希表长度),产生哈希碰撞
1.2.1. 拉链法
将产生冲突的数据用链表存储在对应索引中
哈希表大小适当,否则会产生内存浪费或者时间太长等问题
1.2.2. 线性探测法
向下找一个空位存放碰撞数据
但要求哈希表的长度要大于数据量
1.3. 哈希结构
数组、set集合、map映射
哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
2. 有效的字母异位词
思路:用一个哈希表储存26个字母(题中给出的条件字母ascii码是连续的)
对一个数组中已经出现的字母量做累加
在遍历另一个数组时做累减。
条件成立的结果是哈希表中所有值都为0
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
has = [0] *26
for i in s:
has[ord(i)-ord('a')] += 1
for i in t:
has[ord(i)-ord('a')] -= 1
for i in has:
if i != 0:
return False
return True
3. 两个数组的交集
测试用例数字小于1000,因此可以创建固定长度的数组
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
l1 = [0] * 1001
l2 = [0] * 1001
res = []
for i in nums1:
l1[i] += 1
for i in nums2:
l2[i] += 1
for k in range(1001):
if l1[k] * l2[k] > 0:
res.append(k)
return res
4. 快乐数
无限循环的意思是,求和过程中,Sum重复出现,一旦出现就会循环!
用一个rec表记录已经出现的sum
class Solution:
def isHappy(self, n: int) -> bool:
rec = []
while n not in rec:
rec.append(n)
new_n = 0
nstr = str(n)
for i in nstr:
new_n += int(i) ** 2
if new_n == 1:
return True
else: n = new_n
return False
5. 两数之和
①暴力
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
slow, fast = 0,0
res = []
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
res.append(i)
res.append(j)
return res
return False
②用数组存放哈希表
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
for i, v in enumerate(nums):
if target-v in records:
return [records[target-v],i]
records[v] = i
return []