源码思路来自 代码随想录-贪心-738.单调递增的数字
分析:
由题意,我们要从整数n开始往小找。如果当前位 比 更高一位 的数字小,就得小小小直到更高一位减1,当前位变成9,这样肯定能满足单调递增的要求!
同理,如果 更高位 比 更更高位 的数字也小,那么这个更高位也得变小变小变小直到更更高位减1,更高位变成9.
也就是说,每找到一个位数,比它的高一位数字小,就应该让这个位数变成9,同时高一位数字减1。用标准一些的语言表述的话,就是 一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首先想让strNum[i - 1]减一,strNum[i]赋值9
因此我们需要一个标签,把每个这种情况的数字位都标记起来
但是,不能仅仅把每个标志位变成9就完事了。如果这之间有满足了单调递增的数字,而不变化的话,上一位都变成9了,你还不变,肯定就不满足单调递增了,这样还得遍历一遍,就没完了,而且也没这个必要。因为我们要求的是满足要求的“最大数字”,如果上一位都减1了,小位上肯定都变成9是最大的!
因此,每找到一个不满足单调递增的标志位,就应该把它以及所有小位上的数字都变成9!
C++代码如下:
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string strNum=to_string(n);
int flag=strNum.size();
// 从后往前遍历
for(int i=strNum.size()-1;i>0;i--){
if(strNum[i-1]>strNum[i]){
strNum[i-1]--;
// 记录需要赋值成9的位置
flag=i;
}
}
// 标志位及之后的全赋值为9
for(int i=flag;i<strNum.size();i++){
// 注意是字符
strNum[i]='9';
}
// 转换成数值
// stoi 函数将n进制的字符串转化为十进制,使用时包含头文件string
return stoi(strNum);
}
};
JS代码:
var monotoneIncreasingDigits = function(n) {
n = n.toString()
n = n.split('').map(item => {
return +item
})
let flag = Infinity
for(let i = n.length - 1; i > 0; i--) {
if(n [i - 1] > n[i]) {
flag = i
n[i - 1] = n[i - 1] - 1
}
}
for(let i = flag; i < n.length; i++) {
n[i] = 9
}
n = n.join('')
return +n
};