1 问题
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
示例 1:
输入: N = 10
输出: 9
示例 2:
输入: N = 1234
输出: 1234
示例 3:
输入: N = 332
输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。
2 解法
遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]–,然后strNum[i]给为9,可以保证这两位变成最大单调递增整数。
是从前向后遍历还是从后向前遍历呢?
从前向后遍历的话,遇到strNum[i - 1] > strNum[i]的情况,让strNum[i - 1]减一,但此时如果strNum[i - 1]减一了,可能又小于strNum[i - 2]。
所以从前后向遍历会改变已经遍历过的结果!
那么从后向前遍历,就可以重复利用上次比较得出的结果了,从后向前遍历332的数值变化为:332 -> 329 -> 299
class Solution {
public:
int monotoneIncreasingDigits(int N) {
//将数字转换为字符串
string strNum = to_string(N);
// flag用来标记赋值9从哪里开始
// 设置为这个默认值,为了防止第二个for循环在flag没有被赋值的情况下执行
int pos = strNum.size();
//从后往前遍历字符串,332
for(int i = strNum.size() - 1; i > 0; i--)
{
//后面的数strNum[i]小于前面的数strNum[i-1],不是递增
if(strNum[i] < strNum[i-1])
{
strNum[i - 1]--; //'322'
//记录位置
pos = i;
}
}
for(int i = pos; i < strNum.size(); i++)
{
strNum[i] = '9'; //从i往后均为9
}
return stoi(strNum);
}
};
时间复杂度:O(n) n 为数字长度
空间复杂度:O(n) 需要一个字符串,转化为字符串操作更方便