leetcode 208. 实现 Trie (前缀树)
Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:
- 指向子节点的指针数组children。对于本题而言,数组长度为 26,即小写英文字母的数量。此时children[0] 对应小写字母
a,children[1] 对应小写字母 b,…,children[25] 对应小写字母 z。 - 布尔字段 isEnd,表示该节点是否为字符串的结尾。
需要实现:
- Trie() 初始化前缀树对象。
- void insert(String word) 向前缀树中插入字符串 word 。
- boolean search(String word) 如果字符串 word 在前缀树中,返回
true(即,在检索之前已经插入);否则,返回 false 。 - boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。
- 插入字符串
我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:
子节点存在。沿着指针移动到子节点,继续处理下一个字符。
子节点不存在。创建一个新的子节点,记录在children 数组的对应位置上,然后沿着指针移动到子节点,继续搜索下一个字符。
重复以上步骤,直到处理字符串的最后一个字符,然后将当前节点标记为字符串的结尾。
- 查找前缀
我们从字典树的根开始,查找前缀。对于当前字符对应的子节点,有两种情况:
- 子节点存在。沿着指针移动到子节点,继续搜索下一个字符。
- 子节点不存在。说明字典树中不包含该前缀,返回空指针。
重复以上步骤,直到返回空指针或搜索完前缀的最后一个字符。
若搜索到了前缀的末尾,就说明字典树中存在该前缀。此外,若前缀末尾对应节点的 isEnd 为真,则说明字典树中存在该字符串。
class Trie:
def __init__(self):
self.children = [None] * 26
self.isEnd = False
# 查找前缀
def searchPrefix(self, prefix: str) -> "Trie":
node = self
for ch in prefix:
ch = ord(ch) - ord("a")
if not node.children[ch]:
return None # 为None则不存在该前缀
node = node.children[ch]
return node
def insert(self, word: str) -> None:
node = self
for ch in word:
ch = ord(ch) - ord("a")
if not node.children[ch]:
node.children[ch] = Trie() # 不存在创造新的子节点
node = node.children[ch] # 存在移动到子节点
node.isEnd = True
def search(self, word: str) -> bool:
node = self.searchPrefix(word)
return node is not None and node.isEnd # 不为None且最后指向isEnd说明已经到了最后一个字符=存在
def startsWith(self, prefix: str) -> bool:
return self.searchPrefix(prefix) is not None # 不为None则存在前缀
ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值。