DAY40:贪心算法(九)单调递增的数字(贪心的思路)

文章目录

    • 738.单调递增的数字(暴力解也需要看一下)
      • 暴力解写法
        • 注意:必须引入`isIncreasing`变量的原因
      • 贪心思路
        • 遍历顺序
      • 最开始的写法
        • debug测试:逻辑错误
      • 修改版
        • debug测试
        • int转化为字符串的原因
        • to_string和stoi的用法
      • 总结

738.单调递增的数字(暴力解也需要看一下)

  • 本题暴力解法也需要看一下,虽然暴力解法超时了,但是这种思路是一种很基础的思路,需要了解
  • 数字是没有办法直接采用下标遍历的,如果要for循环遍历每个位置的数字,需要把数字转成字符串string

当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增

示例 1:

输入: n = 10
输出: 9

示例 2:

输入: n = 1234
输出: 1234

示例 3:

输入: n = 332
输出: 299

提示:

  • 0 <= n <= 10^9

暴力解写法

本题题意比较清晰,我们可以首先考虑用暴力来实现一下。也就是给我们一个数值,我们直接从大到小去遍历,并判断每个数值是不是单调递增的。

  • 注意暴力解法不能直接操作i,直接操作i会导致for循环里i–的时候也受到影响!需要用单独的temp来存储i
  • 暴力解法必须需要 bool isIncreasing的原因,是因为while里面break了之后依然会执行外层的for,也就是说会执行for剩下的代码逻辑!我们不能让break出来之后再continue,因此只能加上判断变量,break的情况就判断为false。确定判断为true的时候,才是结束了while循环的时候,此时再返回。
class Solution {
public:int monotoneIncreasingDigits(int n) {for(int i=n;i>=0;i--){int max = INT_MAX;int temp=i;//定义判断变量bool isIncreasing = true;while(temp){//只要还有数字int ten = temp%10;//先取最后一位if(max>=ten)  max=ten;else{isIncreasing = false;break;//只要前一位不满足大于等于,就说明不是单调递增,记为false继续遍历下个数}temp=temp/10;//i减少一位        }//结束while并且满足true,说明找到了if(isIncreasing==true) return i;      }//最后没找到 return 0return 0;}
};

注意:必须引入isIncreasing变量的原因

暴力解法里面需要注意,while循环中的break语句被执行时,它会立即终止当前正在进行的while循环,并且控制流将会继续从break语句跳出while之后,后面的for代码开始执行。这就意味着即使temp并不是单调递增的(在这种情况下,while循环会由于break语句而提前结束),for循环之后的代码也会被执行!这就可能导致不正确的结果被返回。

break只是跳出当前的循环,在while里面的时候,跳出的是while而不是最外层的for

为此,引入了isIncreasing变量。只有在temp是单调递增的情况下(while循环正常结束,而不是由于break语句而提前结束),isIncreasing变量才会保持为true,并且正确的结果i会被返回。

这种解法逻辑正确,但是超时了。

在这里插入图片描述
在这里插入图片描述

贪心思路

我们以32来举例。如果两位不符合要求,前一位需要做-1处理这样后一位才有大于前一位的可能

那么前一位-1之后后一位的值应该取最大的,才能让得到的数值最大

因此32的十位-1得到2 个位取最大得到29。也就是说,遍历数字的时候,凡是前面一位>后面一位,都是前面一位做减一,后面一位取最大值(也就是9)

遍历顺序

以332来举例,如果从前往后遍历,遍历到第二个3的时候,就会发现后面的32换成29之后,整体不满足单调递增了

在这里插入图片描述
从前往后处理的话,因为涉及-1操作,所以后面得到的值,有可能比前面的值要小!会导致遍历到后面不满足单调递增!

从后往前遍历的话,就可以考虑到前一位-1,对前面的数字单调递增特性造成的影响

在这里插入图片描述

最开始的写法

  • 后序遍历的原因,是因为涉及到前一位-1,会对单调递增特性有影响
  • 为了方便挨个数字遍历,把int转换成string
class Solution {
public:int monotoneIncreasingDigits(int n) {string str = to_string(n);//转成字符串就是为了方便遍历for(int i=str.size()-1;i>0;i--){if(str[i-1]<=str[i]) continue;//如果出现i-1>i,就把i换成9else{str[i]='9';str[i-1]=str[i-1]-1;//ASCII码-1}}return stoi(str);//string再转成Int}
};

debug测试:逻辑错误

上面这段代码提交出现了逻辑错误,因为得到的并不是最大值。

在这里插入图片描述

修改版

本题贪心的策略,是遇到了相邻数字前一位>后一位,那么就让前一位变成前一位-1但是此时后面的所有数字都需要变成9

示例如下:

在这里插入图片描述
比如上面的例子,就必须考虑后面有多个小于前面的数字的情况。

  • 修改版为了让小于情况下后面所有的数字都成为9,需要定义一个变量来控制9的起始位置
class Solution {
public:int monotoneIncreasingDigits(int n) {string str = to_string(n);//flag之后的元素都换成9,初值是不用换的情况int flag=str.size();//转成字符串就是为了方便遍历for(int i=str.size()-1;i>0;i--){if(str[i-1]<=str[i]) continue;//如果出现i-1>i,就把i换成9else{flag=i;str[i-1]=str[i-1]-1;//ASCII码-1}}cout<<flag<<endl;//遍历结束之后flag之后元素都是9for(int i=flag;i<str.size();i++){str[i]='9';}return stoi(str);//string再转成Int}
};
  • 时间复杂度:O(n),n 为数字长度
  • 空间复杂度:O(n),需要一个字符串,转化为字符串操作更方便

debug测试

在这里插入图片描述
在这里插入图片描述
修改flag初始值后正确。

int转化为字符串的原因

因为本题需要对数字进行遍历,而我们没有直接的方式去获取和操作其特定位置的数字。因此,通常将整数转换为字符串以便于使用下标进行遍历和比较操作。在这种情况下,使用字符串会使操作更加简单直观。

to_string和stoi的用法

我们此处可以查阅c++string的文档:std::basic_string - cppreference.com

在这里插入图片描述
to_string() 是 C++ 标准库中的一个函数,它用于将各种数值类型(包括整数、浮点数等)转换为字符串。例如,to_string(123) 将返回字符串 "123"

stoi() 函数则是 to_string() 的反向操作,用于将字符串转换为整数。例如**,stoi("123") 将返回整数 123**。值得注意的是,stoi() 函数会忽略字符串开头的空格,直到找到第一个非空格字符。如果这个字符是数字或者正负符号,函数会继续读取剩余部分,直到遇到非数字字符或到达字符串的末尾。

总结

本题只要想清楚个例,例如98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]减一,strNum[i]赋值9,这样这个整数就是89。就可以很自然想到对应的贪心解法了

想到了贪心,还要考虑遍历顺序,只有从后向前遍历才能重复利用上次比较的结果。

最后代码实现的时候,也需要一些技巧,例如用一个flag来标记从哪里开始赋值9。

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

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

相关文章

MQTT资料储备

1、官网 https://mqtt.org/ MQTT 5.0官方协议 https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html 说明&#xff1a;官网可以获取到好多资料&#xff08;比如常用软件、协议、usecase等&#xff09; 2、安装部署EMQX 当前有好多MQTT服务器&#xff0c;初步选择了EM…

一键安装和卸载docker及docker-compose

代码&#xff1a; #!/bin/bashSYSTEMD_PATH/usr/lib/systemd/system/docker.service DOCKER_FILEdocker-20.10.23.tgz DOCKER_COMPOSE_FILEdocker-compose-plugin-2.15.1-3.el8.x86_64.rpm RED\E[1;31m GREEN\E[1;32m YELOW\E[1;33m SHAN\E[1;31;5m RES\E[0mfunction install_…

MySQL 8 group by 报错 this is incompatible with sql_mode=only_full_group_by

根据错误信息大概知道&#xff0c;是sql_mode参数设置为only_full_group_by的不兼容&#xff0c;如果select 的字段不在 group by 中&#xff0c;并且select 字段没有使用聚合函数&#xff08;SUM,MAX等&#xff09;&#xff0c;这个sql查询是被mysql认为非法的&#xff0c;会报…

AI视频智慧安监平台EasyCVR每次重启服务短时间播放后又无法播放,是什么原因?

EasyCVR视频融合平台基于云边端智能协同架构&#xff0c;具有强大的设备接入、视频汇聚管理、全网分发、按需调阅、鉴权播放、智能分析等视频能力与服务。平台开放度高、兼容性强、可支持灵活拓展与第三方集成。 有用户反馈&#xff0c;EasyCVR每次重启服务后&#xff0c;可以短…

[MMDetection]VOC数据格式转为COCO数据格式

以下脚本可以根据创建VOC格式数据集转换为COCO数据集 其中文件组织格式如下 VOC2007 ------Annotations ------***********.xml ------***********.xml -------ImageSets ------train.txt ------test.txt -------JPEGImages ------***********.jpg ------***********.jpg CO…

malloc()与calloc()的辨析

malloc()与calloc()的相同点 两者都是常用的内存分配函数&#xff0c;用于动态分配内存 两者返回值类型都为void*&#xff0c;需要强制转换为所需类型 使用完分配的内存后&#xff0c;都需使用free()函数来释放该内存&#xff0c;防止内存泄漏 malloc()与calloc()的不同点 mal…

flask+分页查询列表显示

import pymysqlfrom flask import Flask, render_template, requestapp Flask(__name__)app.debug Trueapp.route(/) def home():return render_template(Order_page.html)#查询数据以列表的形式返回查询结果 app.route(/Order_list, methods[POST]) def Order_list():db py…

删除数据库记录错误

删除数据库记录错误&#xff1a;Unexpected update count received (Actual: 2, Expected: 1). All changes will be rolled back. 解决&#xff1a;同时删掉ID为8的记录就行了 分析&#xff1a;这种情况是未设置主键约束&#xff0c;插入了相同的记录导致的。推测应该是框架对…

【产生初始解利器】基于蒙特卡洛模拟产生满足固定需求和固定供给的随机供给矩阵

如何生成一个总和是定值的随机矩阵 震惊&#xff0c;如果做一个约束比较强的模型&#xff0c;解的矩阵需要满足很多等式约束&#xff0c;而且都是整数&#xff0c;随机产生初始解很困难&#xff0c;该怎么办&#xff1f; 震惊&#xff0c;如果做一个约束比较强的模型&#xff0…

抖音seo矩阵系统源码开发部署--开发文档分享

目录 一、抖音seo矩阵系统源码自研概况分析 二、 技术开发语言及功能框架 技术要求&#xff1a; 功能框架&#xff1a; 三、 抖音seo矩阵系统开发原则 四、 抖音seo矩阵系统源码开发示例 一、抖音seo矩阵系统源码自研概况分析 关于抖音seo矩阵系统源码自研&#xff0c;在开…

模块化规范

常用模块化有两种规范&#xff0c;commonJS和ES6 一&#xff1a;两者区别 二&#xff1a;如何转义&#xff1f; 我们常遇到的使用场景是&#xff0c;在commonJS的模块里需要引入ES6规范的模块。这时就需要把ES6模块转译为commonJS规范的模块&#xff0c;否则报错 转义工具有…

CMU15-445 2022 Fall 通关记录 —— Project 2:B+ Tree(下篇)

Project 2&#xff1a;B Tree Project #2 - BTree | CMU 15-445/645 :: Intro to Database Systems (Fall 2022) NOTE&#xff1a; 记录完成该Pro中&#xff0c;一些可能会遇到的问题&#xff1a; 本实验中&#xff0c;有很多API是需要自己去实现的&#xff0c;因此&#x…