题目:
Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie() 初始化前缀树对象。
void insert(String word) 向前缀树中插入字符串 word 。
boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。
示例:
输入
[“Trie”, “insert”, “search”, “search”, “startsWith”, “insert”, “search”]
[[], [“apple”], [“apple”], [“app”], [“app”], [“app”], [“app”]]
输出
[null, null, true, false, true, null, true]
解释
Trie trie =new Trie();
trie.insert(“apple”);
trie.search(“apple”); // 返回 True
trie.search(“app”); // 返回 False
trie.startsWith(“app”); // 返回 True
trie.insert(“app”);
trie.search(“app”); // 返回 True
思路:
前缀树是一种树形的数据结构,用来存储和检索字符串,可以类比二叉树来思考前缀树,每个节点有多个分支,最多有26个,因为一共有26个英文字母,每一个节点包括的是一个26维的数组,这个数组表示指向子节点的指针数组,还有一个逻辑值表示当前节点是否是一个字符串的结尾。
插入过程
之前为空的情况,先生成一个对象,就是根节点,比如要插入apple,遍历这个字符串,第一个字母a,在指针数组中索引为0,并且为空,所以在数组的索引0的位置,也就是a的位置,构建一个实例对象,就是一个前缀树节点,当前节点指向这个对象,同样道理添加上另外的四个字母,最终当前节点指向一个前缀树节点,这个节点的指针数组是空的,因为后面没有节点了,到这里要把表示是否为字符串结尾的逻辑值改为真。
查找过程和判断之前已经插入的字符串的前缀之一是否为输入字符串的过程是类似的。
单独写一个判断之前已经插入的字符串的前缀之一是否为输入字符串的函数.
具体过程是遍历字符串,判断当前字符在指针数组中是否存在,如果不存在直接返回空,如果存在就接着遍历下一字符,同时节点指针指向下一前缀树节点。如果在循环中没有返回,最后返回节点。如果能找到搜索的字符串或者前缀,最后返回的节点一定非空。
搜索函数,调用上面写的函数,返回节点是否非空的逻辑值,还有当前节点一定要是字符串的结尾。
判断前缀函数,直接调用上面的函数,返回节点是否非空的逻辑值。
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.children = [None] * 26
self.isend = False
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: 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 searchprefix(self,prefix):
node = self
for ch in prefix:
c = ord(ch) - ord('a')
if not node.children[c]:
return None
node = node.children[c]
return node
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
node = self.searchprefix(word)
return node is not None and node.isend
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
return self.searchprefix(prefix) is not None # 逻辑值
# 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)