算法入门篇八 贪心算法

牛客网 左程云老师的算法入门课

贪心算法

贪心算法的解题步骤 

例子 

题目要求

 解题策略

  • 按照结束时间早的会议先安排,比如先安排【2,4】,当4结束了,所有开始时间小于4的全部淘汰,【1,7】、【3,4】,【2,8】,将【5,6】加入安排,将【7,10】加入安排

 代码 

// package class07;import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;public class Code04_BestArrange {public static class Program {public int start;public int end;public Program(int start, int end) {this.start = start;this.end = end;}}public static class ProgramComparator implements Comparator<Program> {@Overridepublic int compare(Program o1, Program o2) {return o1.end - o2.end;}}public static int bestArrange(Program[] programs, int timePoint) {Arrays.sort(programs, new ProgramComparator());int result = 0;// 从左往右依次遍历所有的会议for (int i = 0; i < programs.length; i++) {if (timePoint <= programs[i].start) {result++;timePoint = programs[i].end;}}return result;}//使用暴力解法public static int bestArrangeForce(Program[] programs,int timePoint){HashSet<Program> set = new HasgSet<>(Arrays.asList(programs));}//会议的集合是set,当前时间是timePoint//返回集合中最多可以安排几个项目public static int process(HashSet<Program>set ,int timepoint){HashSet<Program> candidates = new HashSet<>();for(Program program : set){if(program.start >= timepoint){candidates.add(program);}}//tmp只是为了使用迭代器HashSet<Program> tmp = new HashSet<>(candidates);int result = 0;//尝试将每一个项目,作为第一个安排的项目for(Program program : tmp){candidates.remove(program);int next = process(candidates, program.end);result = Math.max(result,next+1);candidates.add(program);}return result;}public static void main(String[] args) {}}
  • 注意事项:对于HashSet集合中的元素,不可以一边遍历一边删除。需要使用一个tmp集合,将满足条件条件的元素放到tmp中,然后遍历tmp集合,删除原有的集合中的元素
  • 例子:将1到8元素放入到集合set中,需要删除集合中小于5的元素,所以遍历set集合,将小于5的元素收集到tmp集合中,然后遍历tmp集合,删除set集合中小于5的元素,最后遍历打印set集合。

代码

 HashSet<Integer> set = new HashSet<>();set.add(1);set.add(2);set.add(3);set.add(4);set.add(5);set.add(6);set.add(7);set.add(8);HashSet<Integer> tmp = new HashSet<>();//删除集合中比5小的数//不可以一边遍历一边删除元素for(Integer i : set){if(i < 5){tmp.add(i);}}for(Integer i : tmp){set.remove(i);}for(Integer i : set){System.out.println(i);}}

题目要求

给定一个字符串类型的数组str,找到一种拼接方式,使得所有字符串拼接起来形成的字符串具有最小的字典序

  • 字典序:两个字符串在字典中谁先放在前面,谁的字典序就低
  • 思路:两个字符串,str1和str2,如果str1+str2的字典顺序小于str2+str1,则将str1放到str2的前面,否则将str2放到str1的前面
  • 排序具有传递性,不可以歧义,如果是闭环结构是不可以排序的
  • “abc”*“xy”  ==> "abc" * K^2 + "xy" ;* K^2好比与将abc字符串向左边移动2位,K暗指字符串是K进制的数字,数字2是指第二个需要拼接字符串的位数,然后加上字符串xy,整个的过程就像数字运算一样。
  • 使用m(str)= return(K^string长度),所以“abc”*“xy”  ==> "abc" * K^2 + "xy" ==> "abc" * m(xy) + "xy"

代码

package class07;import java.util.Arrays;
import java.util.Comparator;public class Code02_LowestLexicography {public static class MyComparator implements Comparator<String> {@Overridepublic int compare(String a, String b) {return (a + b).compareTo(b + a);}}public static String lowestString(String[] strs) {if (strs == null || strs.length == 0) {return "";}Arrays.sort(strs, new MyComparator());String res = "";for (int i = 0; i < strs.length; i++) {res += strs[i];}return res;}public static void main(String[] args) {String[] strs1 = { "jibw", "ji", "jp", "bw", "jibw" };System.out.println(lowestString(strs1));String[] strs2 = { "ba", "b" };System.out.println(lowestString(strs2));}}

图片解析

  • 根据给出的条件a . b 小于等于 b . a 和 b. c 小于等于 c . b得出a . c 小于等于 c . a,根据上面的式子,得出右边的不等式,将第一个不等式的两边减去b 再乘以 c;第二个不等式左右两边 减去c 乘以a ,这样两个式子会产生一个重合的项,链接其余不等式,化简之后就可以得到 m(c)* a + c 小于等于 m(a)*c + a
  •  

比较排序的过程:

分金条问题

思路

  • 利用小根堆来做,每次选取其中最小的两个数,合并成为一个数,放入到堆中,依次类推。当小根堆里面只有一个数字的时候,就是最终的答案。(哈夫曼编码

代码

package class07;import java.util.Comparator;
import java.util.PriorityQueue;public class Code03_LessMoneySplitGold {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;}public static class MinheapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o1 - o2; // < 0  o1 < o2  负数}}public static class MaxheapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1; // <   o2 < o1}}public static void main(String[] args) {// solutionint[] arr = { 6, 7, 8, 9 };System.out.println(lessMoney(arr));int[] arrForHeap = { 3, 5, 2, 7, 0, 1, 6, 4 };// min heapPriorityQueue<Integer> minQ1 = new PriorityQueue<>();for (int i = 0; i < arrForHeap.length; i++) {minQ1.add(arrForHeap[i]);}while (!minQ1.isEmpty()) {System.out.print(minQ1.poll() + " ");}System.out.println();// min heap use ComparatorPriorityQueue<Integer> minQ2 = new PriorityQueue<>(new MinheapComparator());for (int i = 0; i < arrForHeap.length; i++) {minQ2.add(arrForHeap[i]);}while (!minQ2.isEmpty()) {System.out.print(minQ2.poll() + " ");}System.out.println();// max heap use ComparatorPriorityQueue<Integer> maxQ = new PriorityQueue<>(new MaxheapComparator());for (int i = 0; i < arrForHeap.length; i++) {maxQ.add(arrForHeap[i]);}while (!maxQ.isEmpty()) {System.out.print(maxQ.poll() + " ");}}}

求获取的最大钱数

例子 

  • 按照花费的钱建立小根堆,这个是被锁定的状态,根据初始的钱,比如w=2,解锁(1,3)和(2,6) ,按照利润的高低,压入利润大根堆中,(2,6)(1,3)加入栈中,然后将其从小根堆中删除。然后做第一个项目(2,6),此时自己的钱数为8,那么将小于8的花费的项目解锁,以此类推。

代码

package class07;import java.util.Comparator;
import java.util.PriorityQueue;public class Code05_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> {@Overridepublic int compare(Node o1, Node o2) {return o1.c - o2.c;}}public static class MaxProfitComparator implements Comparator<Node> {@Overridepublic int compare(Node o1, Node o2) {return o2.p - o1.p;}}public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());// 所有项目扔到被锁池中, 花费组织的小根堆for (int i = 0; i < Profits.length; i++) {minCostQ.add(new Node(Profits[i], Capital[i]));}for (int i = 0; i < k; i++) { // 进行K轮// 能力所及的项目,全解锁while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {maxProfitQ.add(minCostQ.poll());}if (maxProfitQ.isEmpty()) {return W;}W += maxProfitQ.poll().p;}return W;}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法入门篇九 暴力递归

牛客网 左程云老师的算法入门课 暴力递归 原则 汉诺塔问题 问题 打印n层汉诺塔从左边移动到最右边的过程 思想 一共六个过程&#xff0c;左到右、左到中&#xff0c;中到左&#xff0c;中到右&#xff0c;右到左&#xff0c;右到中&#xff0c;互相嵌套使用 左到右 将1…

rtsp和sdp

RTSP 是由Realnetwork 和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议 。 实时流协议&#xff08;RTSP&#xff09;建立并控制一个或几个时间同步的连续流媒体&#xff0c;如音频和视频。尽管连续媒体流与控制流交叉是可能的&#xff0c;RTSP本身并不发…

使用javascript实现对于chineseocr的API调用

ChineseOCR在线API 网页地址 界面 提供多种接口调用方式&#xff0c;比如在线调用、Javascript api调用、curl api调用和python api调用四种方式&#xff0c;本次使用javascript api调用的方式进行OCR识别在线Javascript工具 在线工具网页链接在线Base64 转化工具 在线工具…

移动流媒体业务的技术与标准

1 引言   流媒体业务是从Internet上发展起来的一种多媒体应用&#xff0c;指使用流&#xff08;Streaming&#xff09;方式在网络上传输的多媒体文件&#xff0c;包括音频、视频和动画等。   流媒体传输技术的主要特点是以流&#xff08;streaming&#xff09;的形式进行多…

使用python实现对于chineseocr的API调用

ChineseOCR在线API 网页链接 界面 提供多种接口调用方式&#xff0c;比如在线调用、Javascript api调用、curl api调用和python api调用四种方式&#xff0c;本次使用javascript api调用的方式进行OCR识别在线Base64 转化工具 Base64在线小工具代码修改 新增一个变量fill_w…

算法入门篇十 图

图的存储方式 临接表临接矩阵 表达 点集/边集有向图/无向图 Graph&#xff08;大结构就是图&#xff09;&#xff08;包含点集合和边集合&#xff09; import java.util.HashMap; import java.util.HashSet;public class Graph {public HashMap<Integer, Node> nodes;…

超文本传输协议

超文本传输协议 超文本传输协议超文件传输协定(HTTP&#xff0c;HyperTextTransfer Protocol)是因特网上应用最为广泛的一种网络传输协定。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。 目录 介绍请求信息请求方法安全方法超…

利用MFC调用libvlc.dll作一个简单的播放器

简单介绍MFC调用libvlc.dll作一个简单的播放器&#xff0c;抛砖引玉&#xff0c;各位VC达人继续深入研究&#xff0c;Jeremiah对VC确实不太感兴趣&#xff0c;所以就不做太深入的研究了。2009.10.29修改&#xff1a;加入clip_children属性设置。参开第1步。环境&#xff1a; …

使用Remix编写Solidity语言的小例子

设置数值/取数值/加法运算 讲解 uint默认使用256位数的整型view表示这个函数仅仅对于数据仅仅是读取&#xff0c;没有修改操作returns(uint )&#xff0c;如果单纯指定uint&#xff0c;返回的是函数体内的return值&#xff0c;如果包含uint sum,uint SAD_a&#xff0c;那么返…

RTP协议栈简介

流媒体指的是在网络中使用流技术传输的连续时基媒体&#xff0c;其特点是在播放前不需要下载整个文件&#xff0c;而是采用边下载边播放的方式&#xff0c;它是视频会议、IP电话等应用场合的技术基础。RTP是进行实时流媒体传输的标准协议和关键技术&#xff0c;本文介绍如何在L…

使用多线程的方式调用chineseocr_API

ChineseOCR在线API 网页链接 界面 提供多种接口调用方式&#xff0c;比如在线调用、Javascript api调用、curl api调用和python api调用四种方式&#xff0c;本次使用javascript api调用的方式进行OCR识别代码 import glob import base64 import os import requests import …

开源好代码 音视频

VirtualDub 一、简介 图1VirtualDub主界面 VirtualDub是一款开源的音视频捕获、处理软件。VirtualDub也可称为一款多媒体编辑软件&#xff0c;因为它包含了多媒体输入、编辑、处理、输出等各个环节&#xff0c;但是作者并未将它定位为一款多媒体编辑软件&#xff08;参见官网&a…

深入理解Solidity 二

Solidity数据位置 所有复杂的数据类型&#xff0c;即数组、结构和映射类型&#xff0c;都会有一个额外属性“数据位置”&#xff0c;用来指定数据的存储位置&#xff0c;即数据是存储在memory还是存储在storage里面根据上下文环境&#xff0c;IDE会自动指定数据的默认存储位置…

VOIP简介

一、什么是VOIP VOIP全称为&#xff08;VoiceOver Internet Protocol&#xff09;&#xff0c;是一种利用Internet网络进行语音通信的技术&#xff0c;更通俗一点说&#xff0c;就是IP电话。就是以IP分组交换网为传输平台&#xff0c;对模拟的语音信号进行编码压缩&#xff0c…

深入理解Solidity 三

Solidity函数声明和类型 函数的值类型有两类&#xff1a;内部&#xff08;internal&#xff09;类型和外部&#xff08;external&#xff09;类型内部函数只可以在当前合约内部被调用&#xff08;即在当前代码块内&#xff0c;包括内部库函数和继承函数&#xff09;&#xff0c…

安装solc模块4.25版本

使用国产阿里云的cnpm 如果不知道cnpm 参考链接 安装solc模块4.25版本 npm i solc0.4.25 --save -g查看安装是否成功 可以配置软连接使用solc&#xff0c;我的没有配置 solcjs --version

在pycharm中使用conda虚拟环境(conda虚拟环境是已经创建好的),解决python安装包文件很费劲的问题

查看conda的虚拟环境 使用PyCharm连接conda创建的虚拟环境&#xff0c;需要一个前提就是虚拟环境必须存在&#xff0c;使用conda env list命令查看虚拟环境列表打开PyCharm软件 打开pycharm&#xff0c;选择File->setting->Project:****->Project Interperter&#…

完成一个H.265/HEVC码流分析工具

经过大约一个月左右的业余时间&#xff0c;终于初步完成一个H.265/HEVC码流分析工具。时间包括平时的周末、晚上&#xff0c;以及调休的集中时间。当然&#xff0c;中秋回家过节不写代码。截至今天&#xff0c;经过多种H.265序列测试&#xff0c;也有各种工具对比&#xff0c;基…

Golomb及指数哥伦布编码原理介绍及实现

文章来源&#xff1a; https://www.cnblogs.com/wangguchangqing/p/6297792.html &#xff0c; 写的不错&#xff0c;转发出来。 2017年的第一篇博文。 本文主要有以下三部分内容&#xff1a; 介绍了Golomb编码&#xff0c;及其两个变种&#xff1a;Golomb-Rice和Exp-Golo…

解决ipfs 出现Error: can‘t publish while offline: pass `--allow-offline` to override的问题

原因 出现这个问题的原因是因为&#xff0c;ipfs未与公网上的节点相互连接&#xff0c;因此此时处于离线状态 使用场景 部署自己的博客&#xff0c;后期的改动&#xff0c;累计追加在同一个地址&#xff0c;这个地址是唯一的&#xff0c;也就是创建ipfs生成的ID号 步骤 1&…