前缀树 Trie(用于前缀匹配任务)
前缀树主要用于前缀匹配任务,比如输入go会得到goog,googl,google这样的单词。前缀树的题目模板度极高!
做前缀树的题目时,一定要动手画下面这个图,这样思绪才清楚!!!前缀树类似于树,比如我们现在有一堆单词,我们会把所有的单词按照一定的方法都存到树里去,对于Trie来说,我们一般会有一个root节点,但root节点里面我们不会存东西。就为了让它有孩子节点,然后把对应的值存上去。如把goog存进去,就在root节点下新建一个孩子节点把g存进去,以此类推。因为goog是一个单独的单词,所以会在最后一个字母g那里加一个结束符代表goog是一个完整的单词,同时也会在结束符这个地方用一个变量存下这个单词的值即goog这个单词。这样的话利用Trie这个数据结构,如果要搜索某个单词的前缀是否存在时,就非常地方便。下图中的前缀Prefix表示前缀是否存在。
前缀树里的关键点(主要看图):
root节点就是一个什么都没有的Trie()即空哈希表。对于孩子节点,我们一般会用哈希表来存孩子节点,key代表每一个字符即下图的character,value代表每一个孩子节点即一个新的Trie。有时候我们也会用一个数组代替哈希表去做,这个具体取决于题目要求。然后还有个结束标志符号表示是不是一个该有的单词,还有就是对应的值应该是多少,存值是为了返回单词的时候方便。具体见下图
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.lookup = {}
def insert(self, word: str) -> None:
"""
Inserts a word into the trie.
"""
tree = self.lookup
for a in word:
#判断是否有a这个key
if a not in tree:
#这个哈希表中的key是字符, value表示孩子节点(新的一个哈希表)
tree[a] = {}
#覆盖之前的tree为孩子节点, self.lookup就是最终的整个大字典(即存放着所有节点)
tree = tree[a]
#结束标志符Flag
tree["#"] = "#"
def search(self, word: str) -> bool:
"""
Returns if the word is in the trie.
"""
tree = self.lookup
for a in word:
if a not in tree:
return False
tree = tree[a]
if "#" in tree:
return True
return False
def startsWith(self, prefix: str) -> bool:
"""
Returns if there is any word in the trie that starts with the given prefix.
"""
tree = self.lookup
for a in prefix:
if a not in tree:
return False
tree = tree[a]
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)