208. 实现 Trie (前缀树) - 力扣(LeetCode)
关于前缀树:数据结构与算法之美:35 | Trie树:如何实现搜索引擎的搜索关键词提示功能?
细节就不多描述了
假设所有的输入都是由小写字母 a-z 构成的:那么我们可以采取数组存储的方式。
struct TrieNode{
const static int MaxBranchNum = 26;
char data;
bool isEnd = false;
vector<TrieNode*> children = vector<TrieNode*>(26);
TrieNode(char data) : data(data){};
};
class Trie {
public:
Trie() : root(new TrieNode('/')) {}
void insert(string word) {
TrieNode* p = root;
for(int i = 0; i < word.size(); ++i){
int idx = word[i] - 'a';
if(p->children[idx] == NULL)
p->children[idx] = new TrieNode(word[i]);
p = p->children[idx];
}
p->isEnd = true;
}
bool search(string word) {
auto p = root;
for(int i = 0; i < word.size(); ++i){
int idx = word[i] - 'a';
if(p->children[idx] == NULL) return false;
p = p->children[idx];
}
return p->isEnd;
}
bool startsWith(string prefix) {
auto p = root;
for(int i = 0; i < prefix.size(); ++i){
int idx = prefix[i] - 'a';
if(p->children[idx] == NULL) return false;
p = p->children[idx];
}
return true;
}
private:
TrieNode* root;
};
使用内置数组,TrieNode
的data成员变量其实并不需要:
struct TrieNode{
bool isEnd = false;
TrieNode* children[26] = {NULL};
};
class Trie {
public:
Trie() : root(new TrieNode) {}
void insert(string word) {
TrieNode* p = root;
for(int i = 0; i < word.size(); ++i){
int idx = word[i] - 'a';
if(p->children[idx] == NULL)
p->children[idx] = new TrieNode;
p = p->children[idx];
}
p->isEnd = true;
}
bool search(string word) {
auto p = root;
for(int i = 0; i < word.size(); ++i){
int idx = word[i] - 'a';
if(p->children[idx] == NULL) return false;
p = p->children[idx];
}
return p->isEnd;
}
bool startsWith(string prefix) {
auto p = root;
for(int i = 0; i < prefix.size(); ++i){
int idx = prefix[i] - 'a';
if(p->children[idx] == NULL) return false;
p = p->children[idx];
}
return true;
}
private:
TrieNode* root;
};
当然不使用数组,使用哈希表也是可以的:
class TrieNode {
unordered_map<char, TrieNode*> children;
};