算法笔记——前缀树、贪心算法(更新ing.......

前缀树、贪心算法

  • 一、前缀树
    • 1.什么是前缀树
    • 2.如何生成前缀树
  • 二、贪心算法
    • 1.拼接字符串
    • 2.金条问题
    • 3.项目会议时间问题
    • 4.项目收益最大化
    • 4.随时获得数据流的中位数

一、前缀树

1.什么是前缀树

  • 前缀树一般指字典树 这是指一种结构而不是一类题(注意信息是在树的路上

典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

  • 它有三个基本性质
    1)根节点不包含字符,除根节点外每一个节点都只包含一个字符
    2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
    3)每个节点的所有子节点包含的字符都不相同
    算法笔记——前缀树、贪心算法(更新ing......._第1张图片
    用上图来举例的话,这就是一颗前缀树,其中节点用圆圈来表示,“abc”等字符加入到这颗树中作为路径加入,而不是以节点的形式,它们都在路上,有就复用,没有就创建。同时每个字符在加入时均从头结点出发,因此可以看到“abc”和“bck”为两个分支,同时“abc”和“abd”前半段为一个分支,最后形成两个分支。

2.如何生成前缀树

算法笔记——前缀树、贪心算法(更新ing......._第2张图片

下面看一下代码:

  • 节点的数据结构表示
public class TrieTree {
   
    //点的数据结构描述
    public static class TireNode{
   
        //沿途的path增加  最后一个点end++
        public int path; 在加前缀树时,这个节点到达过多少次,通过了多少次
        public int end; 这个节点是否是一个字符串的结尾节点,如果是的话,它是多少个字符串的结尾节点
        public TireNode[] nexts;//下级的路
        //字符种类过多 大于26,这里可以用 HashMap nexts,如果想有序,那就用TreeMap

        public TireNode(){
   
            path = 0;
            end = 0;
            //通过下级有没有节点来表示下级是否有路
            //nexts[0]==null 表示没有走向'a'的路
            //nexts[0]!=null表示有走向'a'的路
            //nexts[25]!=null表示有走向'z的路
            nexts = new TireNode[26];
        }
    }

    //树的数据结构
    public static class Trie{
   
        private TireNode root; //头节点
        //根节点的path值表示你加入了多少个字符串(有多少个字符串是以空串作为前缀的
        public Trie(){
   
            root = new TireNode();//头节点的表达方式
        }
        //加入字符串
        public void insert(String word){
   
            if (word == null){
   
                return;
            }
            char[] words = word.toCharArray();//转化为字符类型的数组
            TireNode node = root; //node从根节点出发
            node.path++; //根节点一上来有一条路要走,一上来path++
            int index = 0;//判断走哪条路
            for (int i = 0; i < words.length; i++){
   //遍历字符数组
                index = words[i] - 'a';// 由字符,对应成走向哪条路(a对应的index是0,b是1)
                //接下来判断这个要走的路之前有吗,有节点不走if,不新建,直接跳过去复用
                if (node.nexts[index] == null){
   //当前node下一级路上是否是空节点(其实就是问有无走向a的路
                    node.nexts[index] = new TireNode();//没有把这个节点新建出来
                }
                node = node.nexts[index];//node移动到下级节点
                node.path++;//然后把新来到node的pass++
            }
            node.end++; //字符串走完了 最后一个node的end++
        }

        //删除
        public void delete(String word){
   
            //首先确定树中之前确实加入过word,加入过才删除
            if (search(word) != 0){
   
                TireNode node = root;
                char[] chars = word.toCharArray();
                int index = 0;
                //删除的时候,沿途path--,最后一个节点再加一份end--
                for (int i = 0; i < chars.length; i++){
   
                    index = chars[i] - 'a';
                    //如果一个节点的p值删成0了,后序所有路都不要了
                    路径信息某个节点减一变成0,
                    //意味着接下来的字符串全部都是所需要删除的字符串,
                    //所以下面的字符串直接设置为null
                    if (--node.nexts[index].path == 0){
   
                        node.nexts[index] = null;
                        return;
                    }
                    node = node.nexts[index];
                }
                node.end--;
            }

        }

        //查询  查询这个word之前加入过几次
        public int search(String word){
   
            if (word == null){
   
                return 0;
            }
            char[] chars = word.toCharArray();
            TireNode node = root;//从根节点开始
            int index = 0;
            for (int i = 0; i < chars.length; i++){
   
                index = chars[i] - 'a';
                //发现没路了,但是字符还有的话(举个例子,我加入过abc,但你却让我查abcdefg。当然查不到
                if (node.nexts[index] == null){
    //或者说一上来就找不到
                    return 0;
                }
                //如果有 一直找下去
                node = node.nexts[index];
            }
            //走完了字符串,这里的end就是加入过几次
            return node.end;
        }

        //所有加入过的字符中,有几个是以pre这个字符作为前缀的
        public int prefixNumber(String pre){
   
            if (pre == null){
   
                return 0;
            }
            char[] pres 

你可能感兴趣的:(左神算法笔记,算法,数据结构,贪心算法,leetcode,堆栈)