字典树(Trie)
定义
字典树按功能理解的话可以叫做单词查找树,或者键树,是一种树形结构,是哈希树的变种。典型应用在统计与排序大量的字符串,所以经常被搜索引擎系统用于文本词频的统计。
字典树将单词拆分成树的节点,沿着树的路径就形成了该单词,可以用50多个树节点(a-z,A-Z),以及20多层(英文字母最大长度)来表示单词。
字典树是一种以空间换时间的做法,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。输入一些字符串(前缀),以此节点为开头,该节点下的节点就是以输入的词为前缀所包含的所有词了。
trie树常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。
存储结构
每条边的叶子节点为一个单词,中间的节点只能表示某些单词拥有这些前缀,不能表示单词,即路径到底才是一个单词,中间暂停都不是单词。
代码表现
class TrieNode:
def __init__(self):
self.children = {} # 字典
self.is_word = False # the end of a word
代码应用
1. 字典树的设计
leetcode 208
Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
- Trie() 初始化前缀树对象。
- void insert(String word) 向前缀树中插入字符串 word 。
- boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
- boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。
思路:
- 利用字典保存字典的节点。
- 判断是否在字典中就可以完成相应的操作
class Trie:
def __init__(self):
self.root = {}
self.is_word = False
def insert(self, word: str) -> None:
node = self.root
for char in word:
if char not in node:
node[char]={}
node = node[char] # move to next node
node['is_word']=True
def search(self, word: str) -> bool:
node =self.root
for char in word:
if char not in node:
return False
node = node[char]
return node.get('is_word',False)
def startsWith(self, prefix: str) -> bool:
node =self.root
for char in prefix:
if char not in node:
return False
node = node[char]
return True
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)
2. 单词拆分
leetcode 139
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
思路:
- 初始化dp=[false,…],长度为n+1,dp[i]表示前i位能否用wordDict中的单词表示
- Dp[0]=True,空字符串可以被表示。
- 循环word[i,n),j in[i+1,n+1]
- Dp[i] and s[i:j] in wordDict dp[j]=True
- 返回dp[n]
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
n=len(s)+1
dp=[False] *n
dp[0]=True
for i in range(n):
for j in range(i+1,n+1):
if dp[i] and (s[i:j] in wordDict):
dp[j]=True
return dp[-1]