前缀树的构造
什么是Trie树
Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
它有3个基本性质:
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同。
构建Trie树
好比假设有b,abc,abd,bcd,abcd,efg,hii 这6个单词,我们构建的树就是如下图这样的:
如上图所示,对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。
Leetcode例题
力扣208:实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
class Trie:
def __init__(self):
self.lookup = {}
def insert(self, word: str) -> None:
#构造前缀树
tree = self.lookup
for a in word:
if a not in tree:
tree[a] = {}
tree = tree[a]
tree['#'] = '#'
def search(self, word: str) -> bool:
tree = self.lookup
for a in word:
if a not in tree:
return False
tree = tree[a]
return '#' in tree
def startsWith(self, prefix: str) -> bool:
tree = self.lookup
for a in prefix:
if a not in tree:
return False
tree = tree[a]
return True
思路就是把所有的words构造一个前缀树,例如words = [“oath”,“pea”,“eat”,“rain”]。则构造出来的前缀树是{'o': {'a': {'t': {'h': {'end': '1'}}}}, 'p': {'e': {'a': {'end': '1'}}}, 'e': {'a': {'t': {'end': '1'}}}, 'r': {'a': {'i': {'n': {'end': '1'}}}}}
。
只要遍历给定的数组然后dfs就可以了。
例如从矩阵的‘o’开始时,先判断‘o’是否在trie中,如果不在就退出。如果在,那么trie = trie[‘o’]。trie[‘o’] = {‘a’: {‘t’: {‘h’: {‘end’: ‘1’}}}。下面dfs试探四周的字母,即‘a’和‘e’,之后的过程和之前一样。当遇到’end’的时候,说明找到了一个符合的单词,此时把他加入res,并且把trie[‘end’]更改,以免重复访问。代码如下
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
#构造前缀树
trie = {}
for word in words:
t = trie
for a in word:
if a not in t:
t[a] = {}
t = t[a]
t['end'] = '1'
res = []
row = len(board)
col = len(board[0])
#dfs递归试探
def dfs(i,j,trie,s):
c = board[i][j]
if c not in trie:return
trie = trie[c]
if 'end' in trie and trie['end']=='1':
res.append(s+c)
#防止重复访问
trie['end'] = '0'
board[i][j] = '#'
for x,y in [[-1,0],[0,-1],[1,0],[0,1]]:
tmp_i = i+x
tmp_j = j+y
if 0<=tmp_i<row and 0<=tmp_j<col and board[tmp_i][tmp_j]!='#':
dfs(tmp_i,tmp_j,trie,s+c)
board[i][j] = c
for i in range(row):
for j in range(col):
dfs(i,j,trie,'')
return res