题目
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
示例
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
分析:
三个功能
insert
将一个单词插入前缀树。
search
给一个单词搜索是否在前缀树中。
startsWith
给一个字符串,看前缀树中是否有单词以此为前缀。
两个变量
Trie* next[26]
和isEnd
。前者是一个指针数组,即next数组中有26个指针,每个指针指向一个Trie对象。所有元素初始为空指针。当insert时,若当前字符代表的位置为空时,则创建新的Trie对象,让该位置指向这个新的对象,新的对象中同样包含这样两个元素。后者表示当前对象代表的字符,是否为一个单词的最后一个字符,这个变量用来search。
代码
class Trie {
private:
Trie* next[26] = { nullptr };
bool isEnd = false;
public:
/** Initialize your data structure here. */
Trie() {}
/** Inserts a word into the trie. */
void insert(string word) {
Trie* node = this; // node指向当前对象
for ( auto c : word ) {
int index = c - 'a';
if ( node->next[index] == nullptr ) {
node->next[index] = new Trie();
}
node = node->next[index];
}
node->isEnd = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie* node = this;
for ( auto c : word ) {
int index = c - 'a';
if ( node->next[index] == nullptr ) {
return false;
}
node = node->next[index];
}
return node->isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* node = this;
for ( auto c : prefix ) {
int index = c - 'a';
if ( node->next[index] == nullptr ) {
return false;
}
node = node->next[index];
}
return true;
}
};
/**
* 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);
*/