【LeetCode贪心#11】单调递增的数字(详解)
单调递增的数字
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
- 输入: N = 10
- 输出: 9
示例 2:
- 输入: N = 1234
- 输出: 1234
示例 3:
- 输入: N = 332
- 输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数
思路
题意解析
题目举的例子有点不太好理解,这里再举一个吧
- 输入: N = 32
- 输出: 29
什么意思呢?就是32这个输入数,其不满足各个位数上的数字是单调递增的规则
因此需要找一个比32小但是尽可能大的整数,该整数还要满足各个位数上的数字单调递增的规则
那么29显然是符合条件的
解法
用人脑想可以想到上面情况中29是符合条件的数,但是用算法怎么实现?
如果去遍历nums(32),可以得到nums[i](2)小于nums[i - 1](3)
此时出现了单调递减,不符合条件,需要去找比nums小的一个最大单调递增整数
怎么找?
因为32已经是单调递减了,所以个位上的2无论怎么变化都不能逆转递减的趋势,因此需要把十位减小使整体满足递减的要求,按照上述逻辑可以得到22
因为大于等于都算递增,所以此时的22已经满足单调递增的条件了,接下来需要达成最大整数这个条件
显然22不是小于32的数中满足单调递增的最大整数,在2X中找最大整数,那X只要取9就可以使整体最大,所以满足所有条件的数是29
总结一下:
当遍历遇到单调递减的两位数时,可以直接将十位数减1,然后个位取9,得到小于当前这两位数的最大单调递增整数
这里也可以确认 ,遍历时我们是两个两个数来判断是否符合条件的
遍历nums的顺序
问题又来了,遍历nums的顺序是什么呢?
先说结论,应该从后先前遍历
举个例子:
- 输入: N = 332
- 输出: 299
如果从前向后遍历,过程如下:
先得到33,33满足单调递增条件,不管
然后得到32,不满足条件,按照上面的逻辑找到小于32有满足条件的最大整数29,遍历结束
此时整体为329,还是不满足条件
原因是从前向后遍历没有将前面判断得到的结果利用起来
在来看从后向前遍历:
先得的32,不满足条件,修改为29,此时整体为329
然后得到32(基于前一步的结果),还是不满足条件,修改为29,此时整体为299,遍历结束
结果正确
修改9的逻辑
上面其实就是全部的解题逻辑了,但是按照上面的讨论去实现代码时会发现有问题,每次遇到单调递减的数时我们会下意识的直接把9给换到相应位置,但其实这样会出错
举个例子:
- 输入: N = 3232
- 输出: 2999
这个例子的正确答案是2999,如果在实现时按照上面的问题逻辑来的话,得到的结果会是2929
先不说它是不是最大的吧,它就不满足单调递增
因此我们需要一个变量,记录最后一次要改9的位置,然后将其后位置的所有数全部改成9
3 2 3 2
↑ ↑
i-1 i
i 处要改9,此时,flag == 3
3 2 3 2
↑ ↑
i-1 i
此时flag还是3
3 2 3 2
↑ ↑
i-1 i
i 处要改9,此时,flag == 1
遍历结束,将flag往后的所有数都改成9,得到正确结果2999
注意,flag的初始值应该指向数组末尾
代码
注意这里给的输入是一个int,要先把其转化为str才能遍历
然后改完记得再转回来(使用stoi函数)
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum = to_string(n);
int flag = strNum.size();//flag初始值应该指向数组末尾
for(int i = strNum.size() - 1; i > 0; --i){
if(strNum[i - 1] > strNum[i]){//单调递减
strNum[i - 1]--;
// strNum[i] = '9';
flag = i;//记录要修改9的位置
}
}//遍历完成,找到要修改9的位置
for(int i = flag; i < strNum.size(); ++i){//将flag后的数全改为9
strNum[i] = '9';
}
int num = stoi(strNum);//转回int
return num;
}
};
【LeetCode贪心#11】单调递增的数字(详解)的更多相关文章
- 【LeetCode】738. 单调递增的数字
738. 单调递增的数字 知识点:字符串:贪心 题目描述 给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增. (当且仅当每个相邻位数上的数字 x ...
- Java实现 LeetCode 738 单调递增的数字(暴力)
738. 单调递增的数字 给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增. (当且仅当每个相邻位数上的数字 x 和 y 满足 x <= ...
- C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)
上一讲<C++11 并发指南四(<future> 详解一 std::promise 介绍)>主要介绍了 <future> 头文件中的 std::promise 类, ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- C++11 并发指南三(Lock 详解)(转载)
multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...
- C++11 并发指南四(<future> 详解三 std::future & std::shared_future)(转)
上一讲<C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)>主要介绍了 <future> 头文件中的 std::pack ...
- Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现
我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...
- [Swift]LeetCode738. 单调递增的数字 | Monotone Increasing Digits
Given a non-negative integer N, find the largest number that is less than or equal to Nwith monotone ...
- C++11 并发指南三(Lock 详解)
在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...
- C++11 并发指南------std::thread 详解
参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...
随机推荐
- docker部署服务器
Docker部署PostGres docker run -d --name postgres --restart always -e POSTGRES_USER='postgres' -e POSTG ...
- VUE 一些小功能(查重、逻辑删除)
查重就是在表中查找是否有该值,如果有返回0没有则返回1 在API写添加方法时可以直接通过该方法返回值进行添加,如果是0则添加,1则重名 不进行添加 逻辑删除就是在信息表中添加一个删除状态的字段,比 ...
- CCF 202012-2 期末预测之最佳阈值
#include <iostream> #include <bits/stdc++.h> #include <string> using namespace std ...
- 用Python中的hashlib实现md5和sha加密
文章目录 一.用 pandas 读取 Excel 数据 二.加密库 hashlib 三. pandas中的 map() 方法 四.数据加密工具 本文分享知识: pandas读取Excel数据 read ...
- element 换肤
官网操作 https://element.eleme.cn/#/zh-CN/component/custom-theme 然后 执行 et -i 报错了!!! 查了一下,说的是node版本过高?那我就 ...
- xshell和xftp绿色版下载
下载地址:https://www.xshell.com/zh/free-for-home-school/ 点击后页面如下,输入自己的姓名和邮箱然后点击下载即可.登录自己的邮箱获取下载链接.
- Ansible AWX
Ansible简介 ansible是一个非常简单的it自动化平台,使得程序和系统更易于部署.ansible本质是一个进行封装的shell,优点在于它是去中心化的工具,可以直接通过ssh远程管理主机,实 ...
- 网页元素间距测量(better rule插件的使用)
我们在测试UI界面的时候,需要测量各元素大小及元素之间的距离.元素大小,使用F12可以简易的得到数据,但是元素的间距相对来说会比较复杂.这里推荐一款chrome插件better rule,帮助大家测量 ...
- linux 命令下载文件
系统 ubuntu :若提示没有找到命令 请自行下截安装 sz 命令发送文件到本地:# sz filename rz命令本地上传文件到服务器:# rz执行该命令后,在弹出框中选择要上传的文件即可.
- 解决Pycharm不能识别selenium的部分提示代码
这是解决前,pycharm没有提示相关的webelement的代码,例如:send_keys, click 之类的 把鼠标指针放在 selenium 这个单词上就能看到这一串路径 然后找到这个路径的文 ...