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--;

        }
    }
}

  

posted @ 2021-09-02 17:02  sherry001  阅读(50)  评论(0编辑  收藏  举报