题目描述:实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
题目链接:LeetCode.208
思路:
1、使用基础的pyhton语句,暴力查找
2、用字典结构构造前缀树,使用递归法进行相关操作
3、用字典结构构造前缀树,使用迭代法进行相关操作
为什么选择使用字典结构构造前缀树:主要有两个原因,1、由于字母的种类较多,因此使用树结构的话分支较多,结构定义很复杂,需要的空间复杂度较高,而字典可以不限元素大小,可以增加和减小容量;2、由于字典基于hash法创建的,所以查找的时间复杂度和采用树结构的复杂度一样,速度很快。
字典物理结构构造树逻辑结构原理:每一个当前字典的key作为一个节点,代表一个字母;字典的val也是字典,由“val"和其他子节点(逻辑上的后续字母)组成,“val”=1表示此字母是某个单词的最后一个字母,即由根节点到此节点所有字母组成的路径表示一个完整的单词,“Val”=0表示从根节点到此节点条路径是某个单词路径的一部分。
方法1:基于简单的暴力查找
class Trie:
def __init__(self):
self.tree = []
def insert(self, word: str) -> None:
if word not in self.tree:
self.tree.append(word)
return True
def search(self, word: str) -> bool:
if word in self.tree:
return True
else:
return False
def startsWith(self, prefix: str) -> bool:
if prefix in self.tree:
return True
else:
for item in self.tree:
if prefix == item[:len(prefix)]:
return True
return False
方法2:基于字典结构和递归方法
class Trie:
def __init__(self):
self.dic = {} # 定义一种基于字典的树结构{key:{val:0,...}}},val代表是否具有此单词,{}里面是子字典元素集合
def insert(self, word: str) -> None:
def recurse(root, target): # 将字符串转化为自定义的字典形式
if len(target) == 1:
if target[0] not in root:
root[target[0]] = {"val": 1} #如果之前没有生成过此节点创建字典节点标记单词存在
else:
root[target[0]]["val"] = 1
return
else:
if target[0] not in root:
root[target[0]] = {"val": 0}
recurse(root[target[0]], target[1:])
recurse(self.dic, word)
def search(self, word: str) -> bool:
def recurse(root, target):
if len(target) == 1 and target[0] in root and root[target[0]]["val"] == 1:
return True
if len(target) > 1 and target[0] in root:
return recurse(root[target[0]], target[1:])
return False
return recurse(self.dic, word)
def startsWith(self, prefix: str) -> bool:
def recurse(root, target):
if len(target) == 1 and target[0] in root:
return True
if target[0] not in root:
return False
return recurse(root[target[0]], target[1:])
return recurse(self.dic, prefix)
方法3:基于字典结构和迭代方法
class Trie:
def __init__(self):
self.dic = {} # 定义一种基于字典的树结构{key:{val:0,...}}},val代表是否具有此单词,{}里面是子字典元素集合
def insert(self, word: str) -> None:
root = self.dic
for i in word:
if i in root:
root = root[i]
else:
root[i] = {"val": 0}
root = root[i]
root["val"] = 1
def search(self, word: str) -> bool:
root = self.dic
for i in word:
if i not in root:
return False
else:
root = root[i]
return True if root["val"] == 1 else False
def startsWith(self, prefix: str) -> bool:
root = self.dic
for i in prefix:
if i not in root:
return False
else:
root = root[i]
return True