可以当字段树模板使用。
描述
字典树又称为前缀树或者Trie树,是处理字符串常用的数据结构。
假设组成所有单词的字符仅是‘a’~‘z’,请实现字典树的结构,并包含以下四个主要的功能。
1. void insert(String word):添加word,可重复添加;
2. void delete(String word):删除word,如果word添加过多次,仅删除一次;
3. boolean search(String word):查询word是否在字典树中出现过(完整的出现过,前缀式不算);
4. int prefixNumber(String pre):返回以字符串pre作为前缀的单词数量。
现在给定一个m,表示有m次操作,每次操作都为以上四种操作之一。每次操作会给定一个整数op和一个字符串word,op代表一个操作码,如果op为1,则代表添加word,op为2则代表删除word,op为3则代表查询word是否在字典树中,op为4代表返回以word为前缀的单词数量(数据保证不会删除不存在的word)。
对于每次操作,如果op为3时,如果word在字典树中,请输出“YES”,否则输出“NO”;如果op为4时,请输出返回以word为前缀的单词数量,其它情况不输出。
[["1","qwer"],["1","qwe"],["3","qwer"],["4","q"],["2","qwer"],["3","qwer"],["4","q"]]
["YES","2","NO","1"]
struct TrieNode {
int word_cnt;
int prefix_cnt;
bool end;
TrieNode* next[26] = {NULL};
TrieNode() {
word_cnt = 0;//单词个数
prefix_cnt = 0;
end = false;//字符串结束位置
for (int i = 0; i < 26; i++) {
next[i] = NULL;
}
}
};
class Solution {
public:
/**
*
* @param operators string字符串vector<vector<>> the ops
* @return string字符串vector
*/
TrieNode* phead = new TrieNode();
void insert(string word) {
TrieNode* p = phead;
for (char ch : word) {
if (!p->next[ch - 'a']) {
p->next[ch - 'a'] = new TrieNode();
}
p = p->next[ch - 'a'];
p->prefix_cnt++;
}
p->word_cnt++;
p->end = true;
}
void Delete(string word) {
TrieNode* p = phead;
for (char ch : word) {
if (!p->next[ch - 'a']) {
return;
}
p = p->next[ch - 'a'];
p->prefix_cnt--;
}
if (p->word_cnt > 1 && p->end) {
p->word_cnt--;
} else {
p->word_cnt--;
p->end = false;
}
}
string search(string s) {
TrieNode* p = phead;
for (char ch : s) {
if (!p->next[ch - 'a']) return "NO";
p = p->next[ch - 'a'];
}
if (p->end) return "YES";
return "NO";
}
int prefixNumber(string s) {
TrieNode* p = phead;
for (char ch : s) {
if (!p->next[ch - 'a']) return 0;
p = p->next[ch - 'a'];
}
return p->prefix_cnt;
}
vector<string> trieU(vector<vector<string> >& operators) {
// write code here
// write code here
vector<string> ans;
for (auto op : operators) {
string num = op[0], word = op[1];
if (num == "1") insert(word);
else if (num == "2") Delete(word);
else if (num == "3") {
ans.push_back(search(word));
} else if (num == "4") {
int cnt = prefixNumber(word);
ans.push_back(to_string(cnt));
}
}
return ans;
}
};