LeetCode 208 前缀树 C/C++语言
实现一个 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
说明:
你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。
思路1:
Insert插入过程:以字符串长度不断插入,如果该字符index的node->next[index]为空,则需要申请空间存放,如果不为空跳过,直至全部插完,将结束标志位isEnd置1;
Seach搜索过程:同样,以每个字符进行索引,如果为空,则表示没有搜索到该字符串,如果不为空继续,最终返回结束标志位,判断是否有次结尾的字符串;
Startswith计算相同前缀的过程:同样,以每个字符串进行索引,如果为空则表示没有相同前缀的,如果不为空则继续寻找,结束后返回true表示有相同前缀
trieFree释放过程:当指针数组中为空则无需释放,否则调用下一节点,进行递归释放
//const int MaxBranchNum = 26;
class Trie {
private:
bool isEnd ;
Trie* next[26];
public:
Trie() {
isEnd = false;
memset(next,0,sizeof(next));
}
void insert(string word) {
if(word == "")
return;
Trie* node = this;
int index = 0;
for (char c : word) {
index= c - 'a';
if (node->next[index] == nullptr) {
node->next[index] = new Trie();
}
node = node->next[index];
}
node->isEnd = true;
}
bool search(string word) {
if(word == "")
return false;
Trie* node = this;
int index = 0;
for (char c : word) {
index = c - 'a';
if(node->next[index] == nullptr)
return false;
node = node->next[index];
}
return node->isEnd;
}
bool startsWith(string prefix) {
if(prefix == "")
return false;
Trie* node = this;
int index = 0;
for (char c : prefix) {
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);
*/
思路2:C
#define NUM 26
typedef struct TrieNode{
bool isEnd;
struct TrieNode *next[NUM];
} Trie;
/** Initialize your data structure here. */
Trie* trieCreate() {
Trie *root = (Trie *)malloc(sizeof(Trie));
memset(root, 0, sizeof(Trie));
root->isEnd=false;
return root;
}
/** Inserts a word into the trie. */
void trieInsert(Trie* obj, char * word) {
Trie *root = obj;
int len = strlen(word);
for (int i = 0; i < len; i++) {
int index = word[i] - 'a';
if (root->next[index] == NULL) {
root->next[index] = trieCreate();
}
root = root->next[index];
}
root->isEnd = true;
}
/** Returns if the word is in the trie. */
bool trieSearch(Trie* obj, char * word) {
Trie *root = obj;
int len = strlen(word);
for (int i = 0; i < len; i++) {
int index = word[i] - 'a';
if (root->next[index] == NULL) {
return false;
}
root = root->next[index];
}
return root->isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool trieStartsWith(Trie* obj, char * prefix) {
Trie *root = obj;
int len = strlen(prefix);
for (int i = 0; i < len; i++) {
int index = prefix[i] - 'a';
if (root->next[index] == NULL) {
return false;
}
root = root->next[index];
}
return true;
}
void trieFree(Trie* obj) {
Trie *root = obj;
for (int i = 0; i < NUM; i++) {
if (root->next[i] != NULL)
trieFree(root->next[i]);
}
free(root);
}
/**
* Your Trie struct will be instantiated and called as such:
* Trie* obj = trieCreate();
* trieInsert(obj, word);
* bool param_2 = trieSearch(obj, word);
* bool param_3 = trieStartsWith(obj, prefix);