当前位置: 首页 > news >正文

贪心系列专题篇三

目录

单调递增的数字

坏了的计算器

合并区间

无重叠区间

用最少数量的箭


声明:接下来主要使用贪心法来解决问题!!!

单调递增的数字

题目

思路

如果我们遍历整个数组,然后对每个数k从[k,0]依次遍历寻找“单调递增”的数字,对于本题数据量最大为10^9,显然是会超时的,下面将介绍一种贪心解法。

把数字转换成字符串,然后从头到尾遍历整个字符串,当遇到后一个字符小于当前一个字符时,把当前字符-1,之后的字符全都修改正字符'9'。如下:

但是这种方法还是有缺陷的,比如下面的这种情况,

因此,我们需要对上面的贪心策略进行修改,修改后的贪心策略如下:

贪心策略

把数字转换成字符串,然后从头到尾遍历整个字符串,当遇到后一个字符小于当前一个字符时,向前寻找和当前字符相等的字符,把与当前字符相等的字符的最左段字符字符-1,之后的字符全都修改正字符'9'。如下:

代码

class Solution {
public:int monotoneIncreasingDigits(int n) {string s=to_string(n);int m=s.size();int i=0;while(i+1<m && s[i]<=s[i+1])i++;if(i+1==m) return n;else{while(i-1>=0 && s[i-1]==s[i])i--;s[i]=s[i]-1;for(i=i+1;i<m;i++)s[i]='9';}return stoi(s);}
};
坏了的计算器

题目

思路

因为可对startValue进行乘2和减1操作,但是要想由startValue变换成target,毫无确定的头绪可言.

贪心策略

采用“正难则反”的思想,我们可以想想如何将target变换成startValue,此时有两种操作,分别为除2和加1,而此时可以分两种情况进行讨论,分别是:

当target<startValue,当target为奇数时,由于startValue为整数,此时只能进行+1操作;

                            当target为偶数时,要想变换成startValue,此时只能进行+1操作,

即当target<startValue时,变换操作次数为startValue-target.

当target>startValue,当target为奇数时,由于startValue为整数,此时只能进行+1操作;

                            当target为偶数时,要想变换成startValue,可进行除2和+1操作混合进行,但是如果混合操作进行的话,要想让target变换成startValue,此时的操作次数是大于只进行除2操作的,因此此时只进行除2操作,

即当target>startValue时,先判断target的奇偶性,进行对应操作,直到target=startValue,或者target<startValue,然后进行target<startValue对应的规则。

代码

class Solution {
public:int brokenCalc(int startValue, int target) {long long ret=0;while(startValue<target){if(target%2==0) target/=2;else target+=1;ret++;}ret+=startValue-target;return ret;}
};
合并区间

题目

思路

首先我们先对集合按区间左端点进行排序,因为如果不排序的话,比较两个区间左端点的大小是需要不断遍历集合的,对集合按区间左端点进行排序后的情况如下:

基准参考区间的左端点记为left,右端点记为right,后一段区间的左端点记为a,右端点记为b。

贪心策略

对于a<=right的区间,需要进行合并,此时需要进行right=max(right,b)的操作即可;

对于a>right的区间, 不需要进行合并, 此时需要进行left=a,right=b和记录已合并区间的操作即可。

但是最后还需要记录最后一个区间。

代码

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {int n=intervals.size();sort(intervals.begin(),intervals.end());vector<vector<int>> ret;int left=intervals[0][0],right=intervals[0][1];for(int i=1;i<n;i++){int a=intervals[i][0],b=intervals[i][1];if(right>=a)right=max(right,b);else{ret.push_back({left,right});left=a,right=b;}}ret.push_back({left,right});return ret;}
};
无重叠区间

题目

思路

首先我们先对集合按区间左端点进行排序,因为如果不排序的话,比较两个区间左端点的大小是需要不断遍历集合的,对集合按区间左端点进行排序后的情况如下:

基准参考区间的左端点记为left,右端点记为right,后一段区间的左端点记为a,右端点记为b。

贪心策略

题目要求保证无重复区间需要删除区间的最少数量,等价于尽可能保留更过数量的区间,使用一个变量ret统计删除区间的数量。

对于a<=right的区间,需要进行删除一个右端点较大的那个区间,此时需要进行right=min(right,b)和ret++的操作即可;

对于a>right的区间, 只需要进行right=b的操作即可。

代码

class Solution {
public:int eraseOverlapIntervals(vector<vector<int>>& intervals) {int n=intervals.size();sort(intervals.begin(),intervals.end());int ret=0;int right=intervals[0][1];for(int i=1;i<n;i++){int a=intervals[i][0],b=intervals[i][1];if(a<right){ret++;right=min(right,b);}elseright=b;}return ret;}
};
用最少数量的箭引爆气球

题目

思路

首先我们先对集合按区间左端点进行排序,因为如果不排序的话,比较两个区间左端点的大小是需要不断遍历集合的,对集合按区间左端点进行排序后的情况如下:

基准参考区间的左端点记为left,右端点记为right,后一段区间的左端点记为a,右端点记为b。

这道题不同于前两道题的明显之处是前两道题求的是并集,而本道题求的是交集。

即求的是下面第二张图的交集个数,而非第一张图。

使用变量ret记录重叠区间个数。

贪心策略

当a<=right时,进行操作right=min(right,b)即可;

当a>right时,进行操作right=b,ret++即可。

代码

class Solution {
public:int findMinArrowShots(vector<vector<int>>& points) {int n=points.size();sort(points.begin(),points.end());int ret=0;int right=points[0][1];for(int i=1;i<n;i++){int a=points[i][0],b=points[i][1];if(a<=right)right=min(right,b);elseright=b,ret++;}ret++;return ret;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【前端 16】使用Ajax发送异步请求
  • 【python】高数计算题难度大?python带你轻松拿下
  • docker部署elasticsearch和Kibana
  • JAVA读取netCdf文件并绘制热力图
  • vue 项目如何自适应 手机,平板等屏幕
  • 人生五大成熟表现
  • 数据面试问题的记录——7.29
  • 慢慢变老的 60 后:普通家庭的现状与未来
  • Vulnhub靶机:AI-WEB-1.0渗透骚操作(超详细讲解教程)
  • 记录阿里云部署gitlab
  • 全开源TikTok跨境商城源码/TikTok内嵌商城+搭建教程/前端uniapp+后端
  • Framework源码整编、单编、烧录过程
  • 科研绘图系列:R语言山脊图(Ridgeline Chart)
  • js实现函数柯里化
  • C++复习的长文指南(二)
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • AHK 中 = 和 == 等比较运算符的用法
  • gulp 教程
  • iOS 颜色设置看我就够了
  • JavaScript异步流程控制的前世今生
  • JS专题之继承
  • MySQL的数据类型
  • React Transition Group -- Transition 组件
  • React+TypeScript入门
  • Redis的resp协议
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 网页视频流m3u8/ts视频下载
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​ubuntu下安装kvm虚拟机
  • ​数据链路层——流量控制可靠传输机制 ​
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • (SpringBoot)第七章:SpringBoot日志文件
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (力扣)循环队列的实现与详解(C语言)
  • (六)激光线扫描-三维重建
  • .“空心村”成因分析及解决对策122344
  • .DFS.
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET : 在VS2008中计算代码度量值
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET开发不可不知、不可不用的辅助类(一)
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .net通过类组装数据转换为json并且传递给对方接口
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [100天算法】-二叉树剪枝(day 48)
  • [20150904]exp slow.txt
  • [20181219]script使用小技巧.txt
  • [Algorithm][综合训练][kotori和气球][体操队形][二叉树中的最大路径和]详细讲解
  • [Android Studio 权威教程]断点调试和高级调试
  • [BZOJ3223]文艺平衡树
  • [C++][ProtoBuf][初识ProtoBuf]详细讲解
  • [C++]二叉搜索树
  • [CCIE历程]CCIE # 20604
  • [ES-5.6.12] x-pack ssl