0%

23:算法小练(3)

简单结束了数组和字符串的学习,现在来继续学习哈希表的内容

设计哈希表

设计哈希集合

哈希表精讲 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

不使用任何内建的哈希表库设计一个哈希集合(HashSet),实现 MyHashSet 类:

  • void add(key) 向哈希集合中插入值 key 。
  • bool contains(key) 返回哈希集合中是否存在这个值 key 。
  • void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MyHashSet(object):
def __init__(self):
self.capacity = 1e5
self.bucket = dict()

def add(self, key:int)->None:
if self.contains(key):
return
if key%self.capacity in self.bucket.keys():
self.bucket[key%self.capacity].append(key)
else:
self.bucket[key%self.capacity] = [key]

def remove(self, key:int)->None:
if not self.contains(key):
return
if key%self.capacity in self.bucket.keys():
if key in self.bucket[key%self.capacity]:
self.bucket[key%self.capacity].remove(key)

def contains(self, key:int)->bool:
if key % self.capacity in self.bucket.keys():
if key in self.bucket[key%self.capacity]:
return True
else:
return False
else:
return False

实际上这里是使用python的字典方法替代了链表的使用

设计哈希映射

哈希表精讲 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

不使用任何内建的哈希表库设计一个哈希映射(HashMap),实现 MyHashMap 类,MyHashMap() 用空映射初始化对象

  • void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中,则更新其对应的值 value 。
  • int get(int key) 返回特定的 key 所映射的 value ;如果映射中不包含 key 的映射,返回 -1 。
  • void remove(key) 如果映射中存在 key 的映射,则移除 key 和它所对应的 value 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyHashMap(object):
def __init__(self):
self.capcity = 1e5
self.bucket = dict()

def put(self, key:int, value:int)->None:
if not key%self.capcity in self.bucket.keys():
self.bucket[key%self.capcity] = {key:value}
else:
self.bucket[key%self.capcity][key] = value

def get(self, key:int)->int:
if key%self.capcity in self.bucket.keys():
if key in self.bucket[key%self.capcity].keys():
return self.bucket[key%self.capcity][key]
return -1


def remove(self, key:int)->None:
if not key%self.capcity in self.bucket.keys():
return
if key%self.capcity in self.bucket.keys():
if key in self.bucket[key%self.capcity].keys():
del self.bucket[key%self.capcity][key]

这里同样是使用字典实现的hash映射,要注意python中常见的用于处理字典的函数操作

哈希集合

哈希集合实际上是一个不包含重复元素的集合数据结构。它只存储元素本身,不存储与元素相关联的值。我们可以用python中的set()和dict()实现,他们实际上都是使用的hash存储结构

快乐数

哈希表精讲 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

编写一个算法来判断一个数 n 是不是快乐数。「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1,那么这个数就是快乐数。如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution(object):
def isHappy(self, n:int)->bool:
temp = set()
while n!=1: # 用于确定计算新的平方和
next = 0
while n!=0:
first = n%10
next += first**2
n //=10
if next in temp: # 用于检查是否存在,如果存在说明不是快乐数
return False
else:
temp.add(next)
n = next # 记得要更新n的值
return True

这里的考察实际上是对于hash存储结构的使用的考察,我们在这里用的是set()

两个数组的交集

哈希表精讲 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

给定两个数组 nums1nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

1
2
3
4
5
class Solution(object):
def intersection(self, nums1:List[int], nums2:List[int])->List[int]:
set1 = set(nums1)
set2 = set(nums2)
return [x for x in set1 if x in set2]

由于python的for ... in ...查找操作相当于对hash表的查找操作,所以直接快捷方式结束了

哈希映射

哈希映射是用于存储键值对结构的,也就是python中的字典结构

同构字符串

哈希表精讲 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

1
2
3
4
5
6
7
8
9
class Solution(object):
def isIsomorphic(self, s:str, t:str)->bool:
st,ts = {},{}
for x,y in zip(s,t):
if x in st and st[x] != y or y in ts and ts[y] != x:
return False
else:
st[x],ts[y] = y,x
return True

这里的zip()用于将多个可迭代对象(列表,数组等)打包成同一个对象,这里是将其打包为了一个字典对象

第一个唯一字符

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1

1
2
3
4
5
6
7
class Solution:
def firstUniqChar(self, s: str) -> int:
frequency = collections.Counter(s)
for i, ch in enumerate(s):
if frequency[ch] == 1:
return i
return -1

???内置函数

我突然后悔了,我本来学算法是希望能学一点相关的算法知识,但是我报了Python 赛道,发现根本不是在学算法,感觉像是在学语法