#include <string> #include <vector> class Trie { private: const static int MaxN = 1500001;//如果数据变多,就改大这个值 int tree[MaxN][26] = { {0} };//tree数组 int pass[MaxN] = {0};//记录走过这个节点的次数 int end[MaxN]={0};//记录以这个节点结尾的单词次数 int cnt;//第cnt个位置 public: Trie() { cnt = 1; } //插入 void insert(string word) { int cur = 1;//每次都要从1开始,也就是根节点开始找 pass[cur]++;//根节点++ for (int i = 0; i < word.size(); i++) { int path = word[i] - 'a';//得到的是整数,例如'z'-'a'=25 //判断这个节点之前是否存在过 if (tree[cur][path] == 0) { //不存在,就++cnt,给予位置 tree[cur][path] = ++cnt; } //更新路径节点 cur=tree[cur][path]; //更新路径的节点的经过次数 pass[cur]++; } //更新以这个字母作为结尾的单词的次数 end[cur]++; } int search(string word) { int cur = 1; for (int i = 0; i < word.size(); i++) { int path = word[i] - 'a'; //如果这个字母在路径中的值为0,说明根本不存在包含这个字母的单词 if (tree[cur][path] == 0) { return 0; } cur = tree[cur][path]; } //结束后,要判断输入的单词是不是前缀树已经插入的单词 //因为有可能插入apple,判断app,app虽然满足前面的条件 //但是app的最后一个p的end值为0,因为它之前没有被插入。 if (end[cur] == 0) return 0; return 1; } int startsWith(string prefix) { int cur = 1; for (int i = 0; i < prefix.size(); i++) { int path = prefix[i] - 'a'; if (tree[cur][path] == 0) { return 0; } cur = tree[cur][path]; } return pass[cur];//返回的是pass数组对应的值 } void deleteTrie(string word) { if (search(word) > 0) { int cur = 1; for (int i = 0; i < word.size(); i++) { int path = word[i] - 'a'; //二维数组的好处就是,如果删除这个节点的路径值 //那么他后面的关联节点全都断开了 //因为cnt必定是不一样的。 if (--pass[tree[cur][path]] == 0) { tree[cur][path] = 0; } cur = tree[cur][path]; } end[cur]--; } } //处理脏数据 void clear() { for (int i = 1; i <= cnt; i++) { fill(&tree[i][0], &tree[i][26], 0); end[i] = 0; pass[i] = 0; } } }; class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param operators string字符串vector<vector<>> the ops * @return string字符串vector */ vector<string> trieU(vector<vector<string> >& operators) { vector<string> res; const string ResULTS[2]={"NO","YES"}; Trie trie; for(vector<string> op:operators) { if(op[0]=="1") { trie.insert(op[1]); } else if(op[0]=="2") { trie.deleteTrie(op[1]); } else if(op[0]=="3") { res.push_back(ResULTS[trie.search(op[1])]); } else if(op[0]=="4") { res.push_back(to_string(trie.startsWith(op[1]))); } } trie.clear(); return res; } };