字典树(前缀树)实现
import java.util.*;
public class Solution {
public String[] trieU (String[][] operators) {
ArrayList<String> ans = new ArrayList<>();
Trie trie = new Trie();
for(int i = 0; i < operators.length; ++i) {
if(operators[i][0].equals("1")) {
trie.insert(operators[i][1]);
} else if(operators[i][0].equals("2")) {
trie.delete(operators[i][1]);
} else if(operators[i][0].equals("3")) {
ans.add(trie.search(operators[i][1]) ? "YES" : "NO");
} else {
ans.add(trie.prefixNumber(operators[i][1]) + "");
}
}
return ans.toArray(new String[0]);
}
public static class TrieNode {
int pass; //前缀个数
int end; //单词个数
TrieNode[] nexts; // 如果单词只有'a'-'z'可以用26大小的数组实现, 复杂情况使用HashMap
TrieNode() {
pass = end = 0;
nexts = new TrieNode[26];
}
}
public static class Trie {
TrieNode root; //空串 root.pass 表示单词总个数
Trie() {
root = new TrieNode();
}
public void insert(String word) {
if(word == null)
return;
char[] chs = word.toCharArray();
TrieNode p = this.root;
++p.pass; //单词总个数加一
for(char ch : chs) {
if(p.nexts[ch - 'a'] == null)
p.nexts[ch - 'a'] = new TrieNode();
p = p.nexts[ch - 'a'];
++p.pass; //前缀个数加一
}
++p.end; //遍历到底, 单词个数加一
}
public void delete(String word) {
if(search(word)) { //确保待删除单词在树中
char[] chs = word.toCharArray();
TrieNode p = this.root;
--p.pass;
// for(char ch : chs) { error
// p = p.nexts[ch - 'a'];
// if(--p.pass == 0) {
// p.nexts = null;
// return;
// }
// }
for(char ch : chs) {
if(--p.nexts[ch - 'a'].pass == 0) { //如果下一个字符的pass减为0, 即为一个单独的分支, 直接移除该分支即可, 然后return
p.nexts[ch - 'a'] = null;
return;
}
p = p.nexts[ch - 'a'];
}
--p.end; //如果遍历到底, 单词个数减一
}
}
public boolean search(String word) {
if(word == null)
return false;
char[] chs = word.toCharArray();
TrieNode p = this.root;
for(char ch : chs) {
if(p.nexts[ch - 'a'] == null) //中途找不到某个字符, 没有这个单词
return false;
p = p.nexts[ch - 'a'];
}
//return true; //不能直接返回true 必须是单词个数
return p.end != 0;
}
public int prefixNumber(String pre) {
if(pre == null)
return 0;
char[] chs = pre.toCharArray();
TrieNode p = this.root;
for(char ch : chs) {
if(p.nexts[ch - 'a'] == null) //中途找不到某个字符, 没有这个前缀
return 0;
p = p.nexts[ch - 'a'];
}
return p.pass; //遍历到底,返回前缀个数
}
}
}
本文来自博客园,作者:brbrbr,转载请注明原文链接:https://www.cnblogs.com/brbrbr/p/15881477.html

浙公网安备 33010602011771号