文章目录
第一章 字典树
字典树的基本性质
核心思想
1、Leetcode 208:实现前缀树
题目描述
解题思路
相对而言比较简单,结构为集合套集合。具体步骤解释在代码中。
代码实现
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
#定义一个tree,以字典的形式
self.look_up={
}
def insert(self, word: str) -> None:
"""
Inserts a word into the trie.
"""
tree=self.look_up
#遍历单词中出现的字母
for char in word:
#如果当前层没有该字母
if char not in tree:
#建立当前层字母的子树
tree[char]={
}
#位置移动到下一层
tree=tree[char]
#在最后加上停止符号
tree["#"]="#"
def search(self, word: str) -> bool:
"""
Returns if the word is in the trie.
"""
tree=self.look_up
#遍历单词中的字母
for char in word:
#如果当前字母不在树中:
if char not in tree:
return False
#如果在,下移一层
tree=tree[char]
#遍历结束后,必须有"#"才可以
return True if "#" in tree else False
def startsWith(self, prefix: str) -> bool:
"""
Returns if there is any word in the trie that starts with the given prefix.
"""
#与search唯一的区别是不需要考虑有没有"#"
tree=self.look_up
for char in prefix:
if char not in tree:
return False
tree=tree[char]
#如果遍历完preflix没有返回False,返回True
return True
2、Leetcode 212:单词搜索
题目描述
解题思路
- 前缀树储存单词信息
- 递归的方式遍历整个棋盘。
代码实现
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
#step 1:建立前缀树
root={
}
#遍历所有词
for word in words:
p=root
#遍历所有字母:
for char in word:
if char not in p:
p[char]={
}
#往下移动一层
p=p[char]
#标记每个单词
p["finish"]=word
#step 2:建立递归函数
m=len(board)
n=len(board[0])
res=[]
def dfs(start,p):
#定位到坐标
i,j=start[0],start[1]
#定位到坐标值
c=board[i][j]
#查看该字母在不在树中,同时查看它到达这个位置后是否有finish
#且将已经查看过的词的节点直接删除掉。
last=p[c].pop("finish",False)
#如果有finish
if last:
#将词添加
res.append(last)
#开始移动该点
board[i][j]="#"
#s四个方向
for x,y in [(1,0),(0,1),(-1,0),(0,-1)]:
new_i=i+x
new_j=j+y
#判断是否符合要求
if 0<=new_i<m and 0<=new_j<n and board[new_i][new_j] in p[c]:
#进入下一层递归
dfs((new_i,new_j),p[c])
#结束递归后,把值变回来
board[i][j]=c
if not p[c]:
p.pop(c)
#开始遍历board
for i in range(m):
for j in range(n):
if board[i][j] in root:
dfs((i,j),root)
return res
第二章 并查集
适用场景:
组团和配对
基本操作
- 创建一个新的并查集
- 把元素x和y所在的集合合并,要求x和y所在的集合不相交,相交则不合并
- 找到元素x所在的集合的代表,也可以判断两个元素是否位于同一个集合
1、Leetcode 200: 岛屿数量
解题思路
- 建立并查集
- 遍历grid,对于每个位置为1得查看他上下左右的值,如果也为1,那么通过并查集联合他们到一起
- 问题:self.rank是做啥的。。发现把它删掉以后并不影响,所以删掉吧哈哈。
代码实现
#并查集
class UnionFind:
def __init__(self,grid):
#统计grid得长宽
m,n=len(grid),len(grid[0])
#计数变量
self.count=0
#并查集
self.parent=[-1]*(m*n)
self.rank=[0]*(m*n)
#对于grid得每个点都建立一个初始集合,统计grid中值为1的数量
for i in range(m):
for j in range(n):
if grid[i][j]=="1":
self.parent[i*n+j]=i*n+j
self.count+=1
def find(self,i):
#根的话会指向自己
if self.parent[i]!=i:
#通过递归不断去查找
self.parent[i]=self.find(self.parent[i]