左程云 Java 笔记--前缀树 贪心算法

2023-11-12


前缀树

介绍前缀树
何为前缀树?如何生成前缀树?
例子:
一个字符串类型的数组arr1,另一个字符串类型的数组arr2。

  • arr2中有哪些字符,是arr1中出现的?请打印。
  • arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印。
  • arr2中有哪些字符,是作为arr1 中某个字符串前缀出现的?请打印
  • arr2中出现次数最大的前缀。
    public static class TireNode{
        public int pass;
        public int end;
//        public HashMap<Char,TireNode> next;
//        public TreeMap<Char,TireNode> next;
        public TireNode[] nexts;

        public TireNode(){
            pass = 0;
            end = 0;
            nexts = new TireNode[26];
        }
    }
    public static class Tire{
        private TireNode root;

        public Tire(){
            root = new TireNode();
        }

        //加入一个字符串
        public void insert(String word){
            if (word == null){
                return;
            }
            char[] chs = word.toCharArray();
            TireNode node = root;
            node.pass++;
            int index  = 0;
            for (int i = 0; i < chs.length; i++) {//从左向右遍历字符
                index = chs[i] - 'a';// 由字符对应走向哪条路
                if (node.nexts[index] == null){
                    node.nexts[index] = new TireNode();
                }
                node = node.nexts[index];
                node.pass++;
            }
            node.end++;
        }


        //word这个词之前加入过几次
        public int search(String word){
            if (word == null){
                return 0;
            }
            char[] chs = word.toCharArray();
            TireNode 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;
        }

        //所有加入的字符串中,有几个是一pre为前缀的
        public int prefixNumber(String pre){
            if (pre == null){
                return 0;
            }
            char[] chs = pre.toCharArray();
            TireNode 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;
        }

        //删除一个节点 沿途p--,最后e--
        public void delete(String word){
            if (search(word) != 0){
                char[] chs = word.toCharArray();
                TireNode 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){
                        node.nexts[index] = null;
                        return;
                    }
                    node = node.nexts[index];
                }
                node.end--;
            }
        }
        

    }

贪心算法

在某一个标准下,优先考虑最满足标准的样本,最后考虑最不满足标准的样本,最终得到一个答案的算法,叫作贪心算法。
也就是说,不从整体最优上加以考虑,所做出的是在某种意义上的局部最优解。
局部最优-?-> 整体最优

例1

一些项目要占用一一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。
给你每-个项目开始的时间和结束的时间(给你- -个数组,里面是一一个个具体
的项目),你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。
返回这个最多的宣讲场次。

public class BestArrange {
    public static class Program{
        public int star;
        public int end;

        public Program(int star,int end){
            this.star = star;
            this.end = end;
        }

        public static class ProgramComparator implements Comparator<Program> {
            @Override
            public int compare(Program o1, Program o2) {
                return o1.end - o2.end;
            }
        }

        public static int bastArrange(Program[] programs,int timePoint){
            Arrays.sort(programs,new ProgramComparator());
            int res = 0;
            //依次遍历所有的会议
            for (int i = 0; i < programs.length; i++) {
                if (timePoint > programs[i].star){
                    res++;
                    timePoint = programs[i].end;
                }
            }
            return res;
        }
    }
}

贪心算法的在笔试时的解题套路
1,实现一个不依靠贪心策略的解法X,可以用最暴力的尝试
2,脑补出贪心策略A、贪心策略B、贪心策略C…
3,用解法X和对数器,去验证每一个贪心策略,用实验的方式得知哪个贪心策略正确
4,不要去纠结贪心策略的证明

字典序排序

在这里插入图片描述

public class lowstString {
    public static void main(String[] args) {

    }
    public static class MtComparator implements Comparator<String>{
        @Override
        public int compare(String o1, String o2) {
            return (o1+o2).compareTo(o2+o1);
        }
    }

    public static String lowstString(String[] strings){
        if (strings == null || strings.length == 0){
            return "";
        }
        Arrays.sort(strings,new MtComparator());
        String res = "";
        for (int i = 0; i < strings.length; i++) {
            res += strings[i];
        }
        return res;
    }
}

贪心策略在实现时,经常使用到的技巧:
1,根据某标准建立一个比较器来排序
2,根据某标准建立一个比较器来组成堆.

例3—哈夫曼编码

一块金条切成两半,是需要花费和长度数值一样的铜板的。比如长度为20的金条,不管切成长度多大的两半,都要花费20个铜板。
一群人想整分整块金条,怎么分最省铜板?
例如,给定数组{10, 20, 30},代表一共三个人,整块金条长度为10+20+30=60。金条要分成10, 20, 30三个部分。如果先把长度 60的金条分成10和50,花费60;再把长度50的金条分成20和30,花费50;一共花费110铜板。但是如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20,花费30;一共花费90铜板。
输入一个数组,返回分割的最小代价。

public static int lessMoney(int[] arr){
        PriorityQueue<Integer> pQ = new PriorityQueue<>();
        for (int i = 0; i < arr.length; i++) {
            pQ.add(arr[i]);
        }
        int sum = 0;
        int cur = 0;
        while (pQ.size() > 1){
            cur = pQ.poll() + pQ.poll();
            sum += cur;
            pQ.add(cur);
        }
        return sum;
    }

例四

输入:
正数数组costs – costs[i]表示i号项目的花费
正数数组profits – profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
正数k – k表示你只能串行的最多做k个项目
正数m – m表示你初始的资金

说明:
你每做完一个项目,马上获得的收益,可以支持你去做下一个项目。
输出:
你最后获得的最大钱数。

public class IPo {
    public static class Node{
        public int p;
        public int c;

        public Node(int p, int c) {
            this.p = p;
            this.c = c;
        }
    }

    public static class MinCostComparator implements Comparator<Node>{
        @Override
        public int compare(Node o1, Node o2) {
            return o1.c-o2.c;
        }
    }

    public static class MaxProfitComparator implements Comparator<Node>{

        @Override
        public int compare(Node o1, Node o2) {
            return o2.p - o1.p;
        }
    }

    public static int fingMaximizedCapital(int k ,int w, int[] Profits,int[] Capital){
        PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());
        PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MinCostComparator());

        for (int i = 0; i < Profits.length; i++) {
            maxProfitQ.add(new Node(Profits[i], Capital[i]));
        }
        for (int i = 0; i < k; i++) {
            while (!maxProfitQ.isEmpty() && minCostQ.peek().c <= w){
                maxProfitQ.add(minCostQ.poll());
            }
            if (maxProfitQ.isEmpty()){
                return w;
            }
            w += maxProfitQ.poll().p;
        }
        return w;
    }

}

堆的一个应用

一个数据流中, 随时可以取得中位数

在这里插入图片描述

N皇后

public class Nqueens {
    public static int num1(int n){
        if (n < 1){
            return 0;
        }
        int[] record = new int[n];
        return process1(0,record,n);
    }

    private static int process1(int i, int[] record, int n) {
        if (i == n){
            return 1;
        }
        int res = 0;
        for (int j = 0; j < n; j++) {
            if (isValid(record,i,j)){
                record[i] = j;
                res += process1(i+1,record,n);
            }
        }
        return res;
    }

    public static boolean isValid(int[] record,int i, int j){
        for (int k = 0; k < i; k++) {
            if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i-k)){
                return false;
            }
        }
        return true;
    }
}

位运算

    public static int num2(int n){
        if (n < 1|| n > 32){
            return 0;
        }
        int limit = n == 32? -1:(1<<n)-1;
        return process2(limit,0,0,0);
    }

    // colLim 列的限制,1的位置不能放皇后,0的位置可以
    // leftDiaLim 左斜线的限制,1的位置不能放皇后,θ的位置可以
    // rightDiaLim 右斜线的限制,1的位置不能放皇后,θ的位置可以
    private static int process2(int limit, int colLim, int leftDiaLim, int rightDiaLim) {
        if (colLim == limit){
            return 1;
        }
        int pos = 0;
        int mostRightOne = 0;

        pos = limit & (~(colLim | leftDiaLim | rightDiaLim));//可以填皇后的位置

        int res = 0;
        while (pos != 0){
            mostRightOne = pos & (~pos+1);
            pos = pos -mostRightOne;
            res += process2(limit,colLim|mostRightOne,
                    (leftDiaLim | mostRightOne) <<1,
                    (rightDiaLim | mostRightOne)>>>1);
        }
        return res;
    }

总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

左程云 Java 笔记--前缀树 贪心算法 的相关文章

  • 如果您不在 Java 中进行克隆,那么您会做什么以及如何称呼它?

    有没有人对 Java 中的复制构造函数 工厂方法等有任何建议或已建立的最佳实践和命名约定 特别是 假设我有一堂课Thing我想要一个返回新值的方法Thing与 a 具有相同的值Thing传入 如果是实例方法 则作为实例 您会将其作为构造函数
  • Java Swing BoxLayout 忽略 AlignmentX

    在下面的代码中 通过调用setAlignmentX with Component LEFT ALIGNMENT我希望在居中的滑块上获得左对齐的标签 由于某种原因 标签也居中 似乎与传递给 setAlignmentX 的值无关 我必须向 se
  • 类型已知,但方法指的是缺失类型

    我对 java 和 Eclipse 不太有经验 但遇到以下问题 我正在写类似的东西 Point3D myPoint myClass myMethod arg 我收到错误 方法 myMethod myType arg 引用缺失的类型 Poin
  • java 中的梵文 i18n

    我正在尝试使用来自互联网的示例 ttf 文件在 java 中使用 i18n 进行梵文 印地文 我可以加载资源包条目 还可以加载 ttf 并设置字体 但它不会根据需要呈现 jlabel 它显示块代替字符 如果我在 Eclipse 中调试 我可
  • Java 小程序在 Mac 上闪烁

    这个问题很奇怪 问题并非在每个平台上都会发生 我在使用 MacOSX 的 Google Chrome 中出现了这种情况 但在 Safari 中却没有出现这种情况 对于使用 Windows 的朋友来说 在 Google Chrome 上运行得
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • 为什么通过 方法向 List 添加元素(类型正确)会出现编译错误? [复制]

    这个问题在这里已经有答案了 我对泛型通配符概念几乎没有疑问 1 假设我有一个方法 void write List
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • 使用 Jena 查询维基数据

    目前 Wikidata 有一个 SPARQL 端点 https query wikidata org https query wikidata org 我想使用 Jena 3 0 1 查询此网站 我使用以下代码 但收到错误消息 端点返回的
  • FileObserver 不适用于 Android 6.0 Marshmallow (API 23) 中的外部存储

    我有一个应用程序可以观察外部存储上的公共目录FileObserver 它运行良好Lollipop设备 我想添加对Marshmallow 所以我用它设置了一台 Nexus 9 平板电脑 在 Marshmallow 设备上 它失败 在 Loll
  • 如何自动转换十六进制代码以将其用作 Java 中的 byte[]?

    我这里有很多十六进制代码 我想将它们放入 Java 中 而不需要向每个实体附加 0x 喜欢 0102FFAB 和我必须执行以下操作 byte test 0x01 0x02 0xFF 0xAB 我有很多很长的十六进制代码 有什么办法可以自动做
  • 但是创建静态实用方法不应该被过度使用吗?如何避免呢? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着时间的推移 java项目中引入了许多实用方法来完成更复杂和简单的任务 当使用静态方法时 我们在代码中引入了紧密耦合 这使得我们的代
  • 如何在Netbeans中设置JList的ListModel?

    我在 Netbeans IDE 的帮助下设计了一个 Swing GUI 该 GUI 包含一个 JList 默认情况下 它使用 QAbstractListModel 将其作为 JList 构造函数中的参数传递以创建该 JList 我想在 Ne
  • 是否可以手动检查 LocateRegistry 是否存在?

    I 已经发现 https stackoverflow com a 8338852 897090一种安全的方式获得LocateRegistry 即使注册表尚不存在 Registry registry null try registry Loc
  • ActiveMQ JNDI 查找问题

    尝试使用 JNDI 运行以下 ActiveMQ http activemq apache org jndi support html http ActiveMQ 20JNDI 并且我的 jboss server node lib 文件夹中有
  • jDBI中如何进行内查询?

    我怎样才能在 jDBI 中执行这样的事情 SqlQuery select id from foo where name in
  • 如何在 spring-data 中强制使用 CrudRepository 进行预加载?

    我有一个实体 其中包含List就是这样lazy默认加载 interface MyEntityRepository extends CrudRepository
  • 从字节数组设置 img src

    我需要设置img src我在对象中拥有的字节数组的属性 img
  • Hibernate 标准接受 %% 值

    我正在使用下面的 Hibernate 代码来过滤workFlowName crt add Restrictions like workFlowName workFlow MatchMode ANYWHERE crt is the crite
  • Java 中序列化的目的是什么?

    我读过很多关于序列化的文章 以及它如何如此美好和伟大 但没有一个论点足够令人信服 我想知道是否有人能真正告诉我通过序列化一个类我们真正可以实现什么 让我们先定义序列化 然后我们才能讨论它为什么如此有用 序列化只是将现有对象转换为字节数组 该

随机推荐

  • C# 常用复习

    Char类型 char a a char b 8 char c L char d char e l char f IsLetter 判断是否是字母 Console WriteLine 判断a是否是字母 Char IsLetter a IsD
  • getaddrinfo简单应用——取得IP地址

    转自 http biancheng dnbcw info linux 265956 html 一个域名可能对应好几个ip地址 a out www baidu com 115 239 210 27 115 239 211 112 getadd
  • 深度学习: Epoch、batchsize、iterations 是什么?

    Epoch 英文 时代 阶段 一波 一轮 一个epoch 表示 所有的数据送入网络中 完成了一次前向计算 反向传播的过程 由于一个epoch 常常太大 分成 几个小的 baches 将所有数据迭代训练一次是不够的 需要反复多次才能拟合 收敛
  • String数组中扩容与填加元素

    String deepCode1 350000 350100 350102 String split deepCode1 split System out println String数组原来的长度为 split length 追加扩容 w
  • vue高德地图的实现 根据经纬度回显地理位

    效果图 1 首先 下载vue amap 插件 2 在main js中引入 import VueAMap from vue amap Vue use VueAMap VueAMap initAMapApiLoader key 你自己的key
  • 深度探索c++对象模型之template中的名称决议方式

    我们应该能够区分以下两种意义 一个是c standard标准中的 scope of the template definition 模板定义域 另一个是c standard标准中的 scope of the template instant
  • SpringMvc

    简述 基于Java实现Mvc模型的轻量级web框架 配置案例过程 导入maven
  • 神经网络——非线性激活

    torch官网 torch nn PyTorch 1 11 0 documentation 非线性变换的主要目的就是给网中加入一些非线性特征 非线性越多才能训练出符合各种特征的模型 常见的非线性激活 ReLU 官网给出的例子 gt gt g
  • C语言求平均成绩小程序(以五个学科为例)

    include
  • 客户好评“收割机”,NPS高达0.7, 实在RPA6.8.0重磅升级解析

    近期 实在智能大模型新品 TARS RPA Agent 发布会召开 通过底层软件架构的全新优化和全面结合大语言模型实现 超进化 持续以AI技术为RPA行业提供领先的超自动化解决方案 同时在发布会上亮相的 还有备受关注的最新版RPA产品 实在
  • buuctf MD5

    打开是一串MD5密文 md5加密后是32位的字符 也有16位的 是去除32位的前后各八位所得 由字母和数字组成 字母要么全是大写要么全是小写 MD5加密是不可逆的加密 无法解密 但是可以爆破出来 给大家推荐一个可以爆破MD5加密的网站htt
  • 小码哥学习感想第一天

    开班须知 本小节知识点 了解 课堂纪律要求 了解 上课的时间和内容安排 了解 学习方法 了解 教学思想和目标 1 课堂纪律要求 手机静音 保持安静 很容易错过精彩 关键瞬间 低调听课 尊重他人 多点反馈 多点互动 积极思考 积极回答 大家一
  • pycharm内无法激活conda虚拟环境

    仅供参考 问题描述 在pycharm终端里conda activate xxx 没报错 但是并没有激活指定的xxx虚拟环境 解决方法 检查是否已将conda加入到系统环境变量内 查找了其他教程 说conda没有加入到环境变量内 但我的已经加
  • 签好软件定制开发合同,需要注意什么

    签订好一份责权分明 细节清晰的软件定制开发合同 对于任何软件定制开发合同的双方而言都是百利无害的 尤其对于软件开发软件定制开发合同这种非常容易引起争议的项目 签订合同的时候更是要慎之又慎 前期做好充足的准备 后期才能达到一个良好的效果 那么
  • Fastapi 学习笔记之请求多个参数

    1 混合使用 Path Query 和请求体参数 from fastapi import FastAPI Path from typing import Optional from pydantic import BaseModel app
  • 人工智能-目标识别:古典目标识别、R-CNN、SPP-NET、Fast-R-CNN、Faster-R-CNN、YOLO

    古典目标识别 第一部分 训练集构造 负样本 使用 select search ss 方法对区域进行融合 gt 计算每个候选区域域真实标记区域 GRadeonTruts GT 之间的重合 如果区域A与GT的重合度在20 50 之间 而且A与其
  • Android LCD(四):LCD驱动调试篇

    关键词 android LCD TFTSN75LVDS83B TTL LVDS LCD电压背光电压平台信息 内核 linux2 6 linux3 0系统 android android4 0 平台 samsung exynos 4210 e
  • Error:Execution failed for task ‘:app:mergeDebugResources‘. > Error: java.util.concurrent.ExecutionE

    我的解决办法是 点击Gradle Scripts下的build gradle Module app 添加如下两行 aaptOptions cruncherEnabled falseaaptOptions useNewCruncher fal
  • 计算机导论 复习 第一章 计算机学什么

    一 核心知识点 1 计算系统构成 硬件 系统软件 操作系统 应用程序 软件 2 算法的特征 算法的高级程序实现方法 3 程序设计语言 机器语言 汇编语言 高级语言 4 计算机发展简史 二 选择题 1 冯 诺伊曼体系结构是现代计算机基础 被人
  • 左程云 Java 笔记--前缀树 贪心算法

    文章目录 前缀树 贪心算法 例1 字典序排序 例3 哈夫曼编码 例四 堆的一个应用 N皇后 总结 前缀树 介绍前缀树 何为前缀树 如何生成前缀树 例子 一个字符串类型的数组arr1 另一个字符串类型的数组arr2 arr2中有哪些字符 是a