C++算法 —— 贪心(4)

文章目录

  • 1、分发饼干
  • 2、最优除法
  • 3、跳跃游戏Ⅱ
  • 4、跳跃游戏Ⅰ
  • 5、加油站
  • 6、单调递增的数字
  • 7、坏了的计算器


1、分发饼干

455. 分发饼干

在这里插入图片描述
其实看完这个题会发现,如果给定的两个数组不排序的话会非常难受,所以无论怎样,先排序。接下来需要比较两个数组的值,可以用双指针来指向。两个数组的两个元素比较时,和之前有相同的思路,如果满足条件,那么后面的元素都比这个元素大,肯定也满足,但为了满足更多次的条件,所以就选用最小的那个值;如果不满足条件,这里就跳过去,找下一个更大的元素去看看能否满足条件。这也就是贪心思想。

    int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int res = 0, m = g.size(), n = s.size();for(int i = 0, j = 0; i < m && j < n; ++i, ++j){while(j < n && s[j] < g[i]) ++j;if(j < n) res++;}return res;}

2、最优除法

553. 最优除法

在这里插入图片描述
无论怎样,假设abcdefg7个数,a / b / c / d / e / f,整个式子就是一个分式,a一定在分子,b一定在分母。对于贪心来说,让分子变大,让分母变小,就是最优解。这道题来看,其实应当让分子变大就是它的最优解,所以接下来就要让分子变大。让分子变大的办法就是在把b ~ f都放到一个括号里,这样就变成了 a * c * d * e * f / b。

    string optimalDivision(vector<int>& nums) {int n = nums.size();if(n == 1) return to_string(nums[0]);if(n == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);string res = to_string(nums[0]) + "/(" + to_string(nums[1]);for(int i = 2; i < n; ++i){res += "/" + to_string(nums[i]);}res += ")";return res;}

3、跳跃游戏Ⅱ

45. 跳跃游戏 II

在这里插入图片描述
这道题意思就是如果是[2, 3, 1, 5, 4],那么在0下标位置时最多可以跳2步到1这个位置。

这道题可以用动规,以i位置为结尾,遍历一遍前面所有的元素,如果能从某个位置跳过来,那就选那个位置,而那个位置存储了到它的最小跳跃数,然后+1即可,但这样是n ^ 2的时间复杂度,思路并不行。

这道题的思路可以是一个类似层序遍历的过程。假设一个数组[2, 3, 1, 1, 4, 2, 6, 7, 1, 5, 8],从0下标开始,是2,我们能够确定跳到3或1这个点,也就是第一次选定起点后确定了下一次起跳的左端点和右端点;接着,3可以跳到1,1,4,而1这里,就加上贪心,因为3跳得远,且它一定比1要至少1,所以1能跳到的,3一定能跳到的,所以这里就只考虑大的数字,跳的区间为114,但是重叠了,重叠部分是2下标处的1,所以把这部分去掉,只看1和4,1就是左端点,4就是右端点;接着从4走,能到2671,这时候14和2671没有重叠的,所有不会划掉一部分,2就是左端点,1就是右端点。这样的过程就是选定了一个点后,就能确定下一次的左端点和右端点,所以很像层序遍历。

这个思路的时间复杂度是O(N)。

    int jump(vector<int>& nums) {int left = 0, right = 0, maxPos = 0, n = nums.size(), res = 0;while(left <= right)//防止跳不到n - 1位置{if(maxPos >= n - 1)//先判断是否已经能跳到最后一个位置return res;for(int i = left; i <= right; ++i){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;res++;}return -1;}

4、跳跃游戏Ⅰ

55. 跳跃游戏

在这里插入图片描述
先看跳跃游戏Ⅱ。

其实就是改两处

    bool canJump(vector<int>& nums) {int left = 0, right = 0, maxPos = 0, n = nums.size();while(left <= right)//防止跳不到n - 1位置{if(maxPos >= n - 1)//先判断是否已经能跳到最后一个位置return true;for(int i = left; i <= right; ++i){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;}return false;}

5、加油站

134. 加油站

在这里插入图片描述
在这里插入图片描述
按照这个题的思路来看,两个数组要同时看,这时不如作为一个数组,因为真正需要的是差。gas和cost两个数组每每对应,用gas的减cost的,比如例1,就得到[-2, -2, -2, 3, 3]。最简单的办法就是暴力解法,依次枚举所有起点,模拟加油的流程。

实际上,这道题可以在暴力解法上改进而得到。差值的数组不需要创建出来,不过下面还是看差值数组。用i表示下标,然后用一个step变量,表示走多少步,比如走0步就还是原地,走1步就到下一个位置,不过要%上数组大小,这样就不会越界了。

    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n = gas.size();for(int i = 0; i < n; i++){int rest = 0;for(int step = 0; step < n; step++){int index = (i + step) % n;rest = rest + gas[index] - cost[index];if(rest < 0) break;}if(rest >= 0) return i;}return -1;}

不过这样肯定超出时间限制。现在基于这个来优化。假设差值数组是abcdefg,从a走到f就不能走了,说明a + b + c + d + e + f < 0,暴力解法就会从b再来一遍,但这样明显做了无用功。上面的式子小于0,那么去掉a,还是小于0,所以就不用管这些了,直接从g位置再出发。这样平均时间复杂度就是O(N)了。

    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n = gas.size();for(int i = 0; i < n; i++){int rest = 0;int step = 0;for(; step < n; step++){int index = (i + step) % n;rest = rest + gas[index] - cost[index];if(rest < 0) break;}if(rest >= 0) return i;i = i + step;}return -1;}

6、单调递增的数字

738. 单调递增的数字

在这里插入图片描述
当然最简单的方法就是暴力枚举,从这个数字到0,判断每一个数字是否是单调递增,找到的第一个就是结果。不过重点在于如何判断单调递增。

对于一个数字,如果想对每一位做一些判断,转换成字符串就好。另一个经典操作就是模10再除10,就能从个位开始拿到每一位。

这个暴力解法的时间复杂度是O(nlogn),取一个数字的每一位的时间复杂度是logn。

但这里不用暴力解法,要用贪心,不过这更像找规律。

从头开始判断,如果发现了不是递增,那要对字符串如何操作?比如123454367,到了5这个位置就不能继续了,但因为要找更小的数字,那么4367不能改为6367。我们可以修改5,把它减1,然后后面的数字全变成9,就是要求的数字。但这里还有问题,如果是连续的几个5之后有个4呢?这样就得把第一个5改成4,后面全变成9。

    int monotoneIncreasingDigits(int n) {string s = to_string(n);int i = 0, m = s.size();while(i + 1 < m && s[i] <= s[i + 1]) ++i;if(i + 1 == m) return n;while(i - 1 >= 0 && s[i] == s[i - 1]) --i;s[i]--;for(int j = i + 1; j < m; ++j) s[j] = '9';return stoi(s);}

7、坏了的计算器

991. 坏了的计算器

在这里插入图片描述
对于小于目标的数,那么乘2会更快地接近目标,但是也有不是最优解的,比如6和目标10。

这道题适合逆着思考,把操作变成除2和+1。
这个题没有小数,所以能除2的只能是偶数,那么遇到奇数的话就只能+1。偶数可以除2,可以+1。把目标值变成原始值,原始值则变成目标值。假设原有的目标值是end,原始值是begin。

针对偶数,如果end <= begin,也就是目标值更小,那么遇到偶数就得+1。如果end > begin,奇数还是只能+1,而偶数,经过证明,其实是先除更优。

    int brokenCalc(int startValue, int target) {//正难则反 + 贪心int res = 0;while(target > startValue){if(target % 2 == 0) target /= 2;else target += 1;res++;}return res + startValue - target;//目标值变成小于原始值了,奇偶数都是+1,所以就是加上差值。}

结束。

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

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

相关文章

项目管理套路:看这一篇绝对够用❤️

写论文必不可少的&#xff0c;就是创建代码并进行实验。好的项目管理可以让实验进行得更加顺利。本篇博客以一次项目实践为例&#xff0c;介绍项目管理的方法&#xff0c;以及可能遇到的问题&#xff0c;并提供一些可行的解决方案。 目录 项目管理工具开始第一步版本管理十分关…

【JavaWeb】TomcatJavaWebHTTP

Tomcat&JavaWeb&HTTP 文章目录 Tomcat&JavaWeb&HTTP一、Tomcat1.1 版本选择及安装1.2 目录1.3 WEB项目部署的方式 二、IDEA中Java Web开发部署流程三、HTTP协议3.1 发展历程3.2 HTTP协议的会话方式3.3 请求报文3.4 响应报文 一、Tomcat Tomcat是Apache 软件基…

php xml数据转数组两种方式

目录 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 方法二、使用PHP内置的DOMDocument类来将XML数据转换为数组的方法 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 $xmlData <root><name>John Doe</name>&l…

NX二次开发UF_CSYS_create_matrix 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_create_matrix Defined in: uf_csys.h int UF_CSYS_create_matrix(const double matrix_values [ 9 ] , tag_t * matrix_id ) overview 概述 Creates a 3 x 3 matrix. 创建…

nodejs+vue+python+PHP+微信小程序-青云商场管理系统的设计与实现-安卓-计算机毕业设计

研究步骤、措施&#xff1a; &#xff08;1&#xff09;与指导老师确定系统主要功能&#xff1b; &#xff08;2&#xff09;做需求分析及功能模块划分&#xff1b; &#xff08;3&#xff09;指导老师通过后&#xff0c;设计出用例图&#xff0c;E-R图&#xff0c;功能模块图 …

【XSLVGL2.0】如何新增一种语言和词条

XSLVGL2.0 开发手册 【XSLVGL2.0】如何新增一种语言和词条 1、概述2、以外置资源的方式增加词条3、以内置资源的方式增加词条4、使用方法1、概述 本文件旨在介绍新增一种语言词条的方法 2、以外置资源的方式增加词条 假设项目需要增加一种英文的词条。一般地,我们采用国际…

老牌开源 SVG 编辑器 SVGEdit 是如何架构的?

大家好&#xff0c;我是前端西瓜哥。这次简单看看 SVGEdit 的架构。 SVGEdit 的版本为 7.2.0。 SVGEdit 一款非常老牌的 SVG 图形编辑器&#xff0c;用于编辑处理 SVG&#xff0c;start 数目前是 5.8k。 它的优点在于经过多年的开发&#xff0c;完成度高&#xff0c;较为成熟&a…

大众博客系统测试报告【改】

一、项目背景 大众博客系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&#xff0c;同时将其部署到云服务器上。前端主要有四个页面构成&#xff1a;登录页、列表页、详情页以及编辑页&#xff0c;以上模拟实现了最简单的大众博客系统。其结合后端…

Tars-GO 开发

默认环境是安装好的 创建服务: tarsgo make App Server Servant GoModuleName Tars 实例的名称&#xff0c;有三个层级&#xff0c;分别是 App&#xff08;应用&#xff09;、Server&#xff08;服务&#xff09;、Servant&#xff08;服务者&#xff0c;有时也称 Object&am…

数据结构——堆的实现

堆的实现-----C语言版 目录&#xff1a;一、堆的实现1.1堆的定义1.2堆的实现1.2.1堆的各个接口1.2.2堆的向上调整1.2.3堆的向下调整1.2.4堆的定义声明和初始化1.2.5堆的数据处理1.2.6堆的判空和堆的数据个数以及堆销毁1.2.7堆的代码实现 二、TOP—K问题 目录&#xff1a; 一、…

vscode项目推送到git

1、打开项目文件 打开文件后点击vs code左侧工具栏中第三个源代码管理图标&#xff0c;点击初始化仓库&#xff0c;此时会创建一个本地仓库会检查该项目中的文件变更 2、创建远程仓库 点击克隆/下载&#xff0c;复制HTTPS地址 3、添加远程地址 1&#xff09;图形化操作 2…

Leetcode刷题之用队列实现栈(C语言版)

Leetcode刷题之用队列实现栈&#xff08;C语言版&#xff09; 一、题目描述二、题目要求三、题目示例四、题目解析Ⅰ、MyStack* myStackCreateⅡ、void myStackPush(MyStack* obj, int x)Ⅲ、int myStackPop(MyStack* obj)Ⅳ、int myStackTop(MyStack* obj)Ⅴ、bool myStackEmp…

文件夹重命名:彻底摆脱数字困扰,批量修改文件夹名去除数字

在日常生活和工作中&#xff0c;经常会遇到需要修改文件夹名称的情况。有时候是因为文件夹名称中包含了数字&#xff0c;有时候是因为文件夹名称不符合规范。无论出于什么原因&#xff0c;修改文件夹名称都是一件非常繁琐的事情。尤其是需要修改大量文件夹名称时&#xff0c;手…

Jenkins 整合 Docker 自动化部署

Docker 安装 Jenkins 配置自动化部署 1. Docker 安装 Jenkins 1.1 拉取镜像文件 docker pull jenkins/jenkins1.2 创建挂载文件目录 mkdir -p $HOME/jenkins_home1.3 启动容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…

k8s部署的java服务查看连接nacos缓存的配置文件

一、问题描述 k8s部署的java服务&#xff0c;使用nacos中的配置文件&#xff0c;需要在缓存中查看该服务具体是使用到了哪些配置文件 二、解决 参考文档: https://nacos.io/zh-cn/docs/system-configurations.html 文档描述如下: 进入java服务容器进入用户目录下的nacos&a…

Java枚举详解

一、什么是枚举类型 枚举类型是一种特殊的数据类型&#xff0c;用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。 在Java中&#xff0c;枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量&#xf…

vue005——vue组件入门(非单文件组件和单文件组件)

一、非单文件组件 1.1、单文件组件的使用 1.1.1、局部注册 1、第一步&#xff1a;创建school组件 2、第二步&#xff1a;注册组件&#xff08;局部注册&#xff09; 3、第三步&#xff1a;使用组件&#xff08;编写组件标签&#xff09; <!DOCTYPE html> <html>…

设计模式—里氏替换原则

1.概念 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说&#xff0c;任何基类可以出现的地方&#xff0c;子类一定可以出现。 LSP是继承复用的基石&#xff0c;只有当衍生类可以替换掉基类&#xff0c;软件单位的功能不受到影…

Mac Ubuntu双系统解决WiFi和WiFi 5G网络不可用问题

文章目录 设备信息1. Ubuntu WiFi不可用解决方式查看Mac的网卡型号根据网卡型号搜索获取到的解决方法查看WiFi名字问题参考链接 2. 解决WiFi重启后失效问题打开终端创建.sh脚本文件编辑脚本文件复制粘贴脚本修改脚本权限创建并编辑systemd service文件复制粘贴下文到systemd se…

只考数据结构,计算机评级C+,成都信息工程大学考情分析

成都信息工程大学(C) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、24专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1715字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 …