208.实现Trie(前缀树)
思路
成员变量flag定义为单词结束的标志,实现search方法时要用到这个flag。字典树的每个节点看作是Tire类的一个对象,next数组(指针数组,每个指针指向一个Tire对象)初始化为nullptr。注意根节点的移动。
class Trie
{
private:
bool flag = false;
Trie* next[26] = { nullptr };
public:
Trie() {}
void insert(const string& word)//插入单词
{
Trie* root = this;
for (const auto& w : word) {
if (!root->next[w - 'a'])//如果字符节点还不存在
root->next[w - 'a'] = new Trie();
root = root->next[w - 'a'];//移动根节点
}
root->flag = true;
}
bool search(const string& word)//查找单词
{
Trie* root = this;
for (const auto& w : word) {
if (!root->next[w - 'a'])
return false;
root = root->next[w - 'a'];//移动根节点
}
return root->flag;
}
bool startsWith(const string& prefix)//查找前缀
{
Trie* root = this;
for (const auto& p : prefix) {
if (!root->next[p - 'a'])
return false;
root = root->next[p - 'a'];
}
return true;
}
};
211.添加与搜索单词
思路
主要是search函数与208题不同。用dfs法,分别度对点.和正常字符dfs。
struct Trie {
Trie* next[26] = { nullptr };
bool flag = false;
};
class WordDictionary {
private:
Trie* root;
public:
/** Initialize your data structure here. */
WordDictionary() {
root = new Trie();
}
/** Adds a word into the data structure. */
void addWord(string word) {
Trie* root_copy = root;
for (const auto& w : word) {
if (!root_copy->next[w - 'a'])//如果字符节点还不存在
root_copy->next[w - 'a'] = new Trie();
root_copy = root_copy->next[w - 'a'];//移动根节点
}
root_copy->flag = true;//结束标记
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
bool search(string word) {
return dfs(root, word, 0);
}
bool dfs(Trie* root, string& word, int i) {
if (!root)
return false;
if (i == word.size())
return root->flag;
if (word[i] != '.')//该字符不为点.
{
if (root->next[word[i] - 'a'])//则去找对应的next是否为null
return dfs(root->next[word[i] - 'a'], word, i + 1);//该字符在前缀树中,继续深度优先搜索
else
return false;//该字符不再前缀树中,直接返回false
}
else {//该字符为点.
for (int j = 0; j < 26; ++j)//遍历出root的后所有字符串路径,只要有一条字符串路径满足就返回true
{
if (root->next[j] && dfs(root->next[j], word, i + 1))
return true;
}
return false;//26条路径都不满足
}
}
};