208. Implement Trie (Prefix Tree)
第一次见到前缀树这个词,就先认识一下吧。
该题题目说:Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
既然是存储字符串,那么一个父亲节点应该有26个子节点。因为保存一个字符串还需要有一个标志位判断该字符是否为最后一个字符。
那么每个节点的结构如下
bool isend;
vector<Trie*> next(26);
那么如何存储字符串呢,因为孩子节点有26个,那么我们就把每个字母映射到26位数字即可,然后遍历字符串,后面一个字符是前一个字符的孩子节点,这样一直往下建立子树。如下图
为了方便,简化如下
那么我们对该题也是建立如上模型即可
代码:
class Trie {
private:
bool isend;
vector<Trie*> next;
public:
/** Initialize your data structure here. */
Trie(): isend(false),next(26) {}
/** Inserts a word into the trie. */
void insert(string word) {
Trie* node=this;
for(char c:word){
c -='a';
if(node->next[c]==NULL) node->next[c]=new Trie(); //一直匹配前缀链,如果没有这个字母代表的孩子节点就创建一个新节点
node=node->next[c];
}
node->isend=true;//遍历到最后一个字符后,要将该字符设为最后一个字符,通过这个置位标志为true
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie* node = this;
for(char c:word){
c -='a';
node=node->next[c];
if(node==NULL) return false; //就判断这个字符代表的节点是不是空的,是说明没有创建也就没有这个字符,就返回false
}
return node->isend; //有可能word只是之前加入的单词的一部分,所以返回isend就能判断word是不是只是一部分即word只是原来的字符串的前缀,或者原来加入过的字符串。
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* node = this;
for(char c:prefix){
c -='a';
node=node->next[c];
if(node==NULL) return false;
}
return true; //和search差不多,只是这个是判断是否是前缀,那么满足前部的字符有就行了。
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/