This commit is contained in:
programmercarl
2023-02-08 17:28:04 +08:00
parent d107b53a4a
commit 1ec9d9bcb4
22 changed files with 146 additions and 148 deletions

View File

@@ -35,6 +35,7 @@
```CPP
class Solution {
private:
// 判断一个数字的各位上是否是递增
bool checkNum(int num) {
int max = 10;
while (num) {
@@ -47,15 +48,15 @@ private:
}
public:
int monotoneIncreasingDigits(int N) {
for (int i = N; i > 0; i--) {
for (int i = N; i > 0; i--) { // 从大到小遍历
if (checkNum(i)) return i;
}
return 0;
}
};
```
* 时间复杂度:$O(n × m)$ m为n的数字长度
* 空间复杂度:$O(1)$
* 时间复杂度O(n × m) m为n的数字长度
* 空间复杂度O(1)
## 贪心算法
@@ -65,20 +66,12 @@ public:
这一点如果想清楚了,这道题就好办了。
**局部最优遇到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
确定了遍历顺序之后,那么此时局部最优就可以推出全局,找不出反例,试试贪心。
@@ -108,8 +101,8 @@ public:
```
* 时间复杂度:$O(n)$n 为数字长度
* 空间复杂度:$O(n)$,需要一个字符串,转化为字符串操作更方便
* 时间复杂度O(n)n 为数字长度
* 空间复杂度O(n),需要一个字符串,转化为字符串操作更方便
## 总结