题目地址:
https://leetcode.com/problems/implement-trie-ii-prefix-tree/description/
要求设计一个前缀树,可以做如下操作:
1、插入一个单词;
2、给定一个单词
s
s
s,问其在树里出现了多少次;
3、给定一个单词
s
s
s,问在树里有多少单词以
s
s
s开始;
4、删除一个单词(只删除其一次)。
题目保证单词都是英文小写的。
每个节点要记录两个东西,一个是该节点所代表的单词的次数,还有一个是经过该节点的单词数量。删除的时候只减少计数即可。代码如下:
class Trie {
public:
struct Node {
Node* ne[26];
int cnt, path_cnt;
Node() : cnt(0), path_cnt(0) { fill(ne, ne + 26, nullptr); }
};
Node* root;
Trie() : root(new Node()) {}
void insert(string s) {
auto p = root;
for (int i = 0, idx; i < s.size(); i++) {
idx = s[i] - 'a';
if (!p->ne[idx]) p->ne[idx] = new Node();
p = p->ne[idx];
p->path_cnt++;
}
p->cnt++;
}
int countWordsEqualTo(string s) {
auto p = root;
for (int i = 0, idx; i < s.size(); i++) {
idx = s[i] - 'a';
if (!p->ne[idx]) return 0;
p = p->ne[idx];
}
return p->cnt;
}
int countWordsStartingWith(string s) {
auto p = root;
for (int i = 0, idx; i < s.size(); i++) {
idx = s[i] - 'a';
if (!p->ne[idx]) return 0;
p = p->ne[idx];
}
return p->path_cnt;
}
void erase(string s) {
auto p = root;
for (int i = 0, idx; i < s.size(); i++) {
idx = s[i] - 'a';
p = p->ne[idx];
p->path_cnt--;
}
p->cnt--;
}
};
初始化时间复杂度 O ( 1 ) O(1) O(1),其余所有操作时间复杂度 O ( l s ) O(l_s) O(ls), l s l_s ls是参数单词的长度,每次操作空间 O ( l s ) O(l_s) O(ls)。