字典树
贪心问题:可以做为贪心的一个策略
前缀树:可以求以ab做为前缀的有几个, 有没有加过个单词
解决的问题:可以知道以什么作为前缀的有几个,而hashMap只能解决整理个单词加入过几次,统计不了前缀的数量
public class TrieTree {
public static class TrieNode{
public int pass;
public int end;
// public HashMap<Character,TrieNode> map=new HashMap<>();
//a->0,b->1,z->25
public TrieNode[] nexts=new TrieNode[26];
}
public static class Trie{
private TrieNode root;
public Trie(){
root=new TrieNode();
}
/**
遍历所有字符,如果该字符没有路了,则建出node,pass++
到最后一个字符时end++
时间复杂度是:所有字符的数量
*/
public void insert(String word){
if(word==null){
return;
}
char[] chs=word.toCharArray();
TrieNode node=root;
node.pass++;
int index;
for(int i=0;i<chs.length;i++){
index=chs[i]-'a';
if(node.nexts[index]==null){
node.nexts[index]=new TrieNode();
}
node=node.nexts[index];
node.pass++;
}
node.end++;
}
/**
查word加入了几次
O(K)
这个hashmap也可以
*/
public int search(String word){
if(word==null){
return 0;
}
char[] chs=word.toCharArray();
TrieNode node=root;
int index=0;
for(int i=0;i<chs.length;i++){
index=chs[i]-'a';
if(node.nexts[index]==null){//说明没有路了,则表示没有加入过
return 0;
}
//否则继续走
node=node.nexts[index];
}
return node.end;
}
/**
有多少个字符串以word为前缀的,这个hashMap做不到
时间复杂度:O(K)
沿途找,返回最后一个字符node的pass
*/
public int preNumber(String word){
if(word==null){
return 0;
}
char[] chs=word.toCharArray();
TrieNode node=root;
int index=0;
for(int i=0;i<chs.length;i++){
index=chs[i]-'a';
if(node.nexts[index]==null){//没有路了,说明没有这个前缀
return 0;
}
node=node.nexts[index];
}
return node.pass;
}
/**
先保证加入过才能删除
沿途pass--
最后end--
注意:如果pass减为0时该怎么办?
把这条路径标为null,jvm会自动回收这个node
*/
public void delete(String word){
if(search(word)==0){
return;
}
char[] chs=word.toCharArray();
TrieNode node=root;
node.pass--;
int index=0;
for(int i=0;i<chs.length;i++){
index=chs[i]-'a';
if(--node.nexts[index].pass==0){
//如果pass=0则
node.nexts[index]=null;
return;
}
node=node.nexts[index];
}
node.end--;
}
}
}