文章目录
题目
图论:208. 实现 Trie (前缀树)
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
提示:
1 <= word.length, prefix.length <= 2000
word 和 prefix 仅由小写英文字母组成
insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次
代码
cpp
//定义前缀树的节点
class TrieNode{
public:
unordered_map<char,TrieNode*>children;
bool isEnd;
TrieNode(){
children.clear();
isEnd=false;//结尾标志
}
};
class Trie {
private:
TrieNode * root;
public:
Trie() {
root=new TrieNode();//前缀树根节点为空
}
void insert(string word) {
TrieNode* cur=root;
for(int i=0;i<word.length();i++){
if(cur->children.count(word[i])==0){//没有当前字母则为该字母创建节点
cur->children[word[i]]=new TrieNode();
}
cur=cur->children[word[i]];//更新当前节点
}
cur->isEnd=true;//将最后一个节点设置标志表示最后一个节点
}
bool search(string word) {
TrieNode* cur=root;//根节点
for(int i=0;i<word.length();i++){
if(cur->children.count(word[i])==0){//判断当前节点是否存在
return false;
}
cur=cur->children[word[i]];
}
return cur->isEnd;//返回最后一个节点的标志为
}
bool startsWith(string prefix) {
TrieNode *cur=root;
for(int i=0;i<prefix.length();i++){
if(cur->children.count(prefix[i])==0){//若当前字符的节点不存在直接返回false
return false;
}
cur=cur->children[prefix[i]];
}
return true;//判断到最后结束,说明都匹配到了则返回true
}
};
原理图

原理解释
提示:算法流程及解释在代码中已标注
TrieNode 节点结构:
unordered_map<char, TrieNode*>:存储字符 → 子节点的映射(可能是26个字母)
bool isEnd:标记当前节点是否是一个完整字符串的结尾
构造函数:初始化子节点为空、结尾标记为 false
Trie 构造函数:
创建一个空的根节点
根节点不存储任何字符
整棵树从根节点开始生长
insert (word) 插入字符串算法步骤:
作用:把一个单词加入前缀树
从根节点开始,用指针 cur 指向当前节点,然后遍历单词的每一个字符
检查当前节点的子节点中是否存在该字符,若不存在则创建一个新节点,存入子节点映射,若存在,不做操作。将 cur 移动到该字符对应的子节点重复 2~4,直到单词所有字符遍历完成将最后一个字符所在节点的 isEnd 设为 true,表示单词结束
search (word) 查找完整单词算法步骤:
作用:判断整个单词是否完整存在
从根节点开始,cur 指向当前节点。遍历单词的每一个字符
检查当前节点是否包含该字符。若不包含直接返回 false,若包含 则 cur 移动到该子节点。字符全部遍历完成后,返回最后节点的 isEnd 标记
true:单词存在
false:只是前缀,不是完整单词
startsWith (prefix) 查找前缀算法步骤:
作用:判断树中是否有以该前缀开头的单词
从根节点开始,cur 指向当前节点。遍历前缀的每一个字符,检查当前节点是否包含该字符。不包含 则 返回 false包含则将 cur 移动到该子节点。所有前缀字符都能顺利走完直接返回 true(不需要判断结尾标记)。