版本更新

This commit is contained in:
youngyangyang04
2021-01-05 00:08:40 +08:00
parent a78113b7d6
commit 9aac98904f
463 changed files with 504 additions and 25041 deletions

View File

@@ -1,123 +0,0 @@
>
# 738.单调递增的数字
给定一个非负整数 N找出小于或等于 N 的最大的整数同时这个整数需要满足其各个位数上的数字是单调递增。
当且仅当每个相邻位数上的数字 x  y 满足 x <= y 我们称这个整数是单调递增的。
示例 1:
输入: N = 10
输出: 9
示例 2:
输入: N = 1234
输出: 1234
示例 3:
输入: N = 332
输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。
# 思路
## 暴力解法
题意很简单,那么首先想的就是暴力解法了,来我提大家暴力一波,结果自然是超时!
代码如下:
```C++
class Solution {
private:
bool checkNum(int num) {
int max = 10;
while (num) {
int t = num % 10;
if (max >= t) max = t;
else return false;
num = num / 10;
}
return true;
}
public:
int monotoneIncreasingDigits(int N) {
for (int i = N; i > 0; i--) {
if (checkNum(i)) return i;
}
return 0;
}
};
```
* 时间复杂度O(n * m) m为n的数字长度
* 空间复杂度O(1)
## 贪心算法
题目要求小于等于N的最大单调递增的整数那么拿一个两位的数字来举例。
例如98一旦出现strNum[i - 1] > strNum[i]的情况非单调递增首先想让strNum[i - 1]--然后strNum[i]给为9这样这个整数就是89即小于98的最大的单调递增整数。
这一点如果想清楚了,这道题就好办了。
**局部最优遇到strNum[i - 1] > strNum[i]的情况让strNum[i - 1]--然后strNum[i]给为9可以保证这两位变成最大单调递增整数**。
**全局最优得到小于等于N的最大单调递增的整数**。
**但这里局部最优推出全局最优还需要其他条件即遍历顺序和标记从哪一位开始统一改成9**。
此时是从前向后遍历还是从后向前遍历呢?
从前向后遍历的话遇到strNum[i - 1] > strNum[i]的情况让strNum[i - 1]减一但此时如果strNum[i - 1]减一了可能又小于strNum[i - 2]。
这么说有点抽象举个例子数字332从前向后遍历的话那么就把变成了329此时2又小于了第一位的3了真正的结果应该是299。
**所以从前后向遍历会改变已经遍历过的结果!**
那么从后向前遍历就可以重复利用上次比较得出的结果了从后向前遍历332的数值变化为332 -> 329 -> 299
确定了遍历顺序之后,那么此时局部最优就可以推出全局,找不出反例,试试贪心。
C++代码如下:
```C++
class Solution {
public:
int monotoneIncreasingDigits(int N) {
string strNum = to_string(N);
// flag用来标记赋值9从哪里开始
// 设置为这个默认值为了防止第二个for循环在flag没有被赋值的情况下执行
int flag = strNum.size();
for (int i = strNum.size() - 1; i > 0; i--) {
if (strNum[i - 1] > strNum[i] ) {
flag = i;
strNum[i - 1]--;
}
}
for (int i = flag; i < strNum.size(); i++) {
strNum[i] = '9';
}
return stoi(strNum);
}
};
```
* 时间复杂度O(n) n 为数字长度
* 空间复杂度O(n) 需要一个字符串,转化为字符串操作更方便
# 总结
本题只要想清楚个例例如98一旦出现strNum[i - 1] > strNum[i]的情况非单调递增首先想让strNum[i - 1]减一strNum[i]赋值9这样这个整数就是89。就可以很自然想到对应的贪心解法了。
想到了贪心,还要考虑遍历顺序,只有从后向前遍历才能重复利用上次比较的结果。
最后代码实现的时候也需要一些技巧例如用一个flag来标记从哪里开始赋值9。
就酱,循序渐进学算法,认准「代码随想录」!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20201124161234338.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉题解对你有帮助,不要吝啬给一个👍吧!**