Trie
字典树
贪心问题:可以做为贪心的一个策略
前缀树:可以求以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--; } } }