力扣738. 单调递增的数字
题目来源(力扣):
https://leetcode.cn/problems/monotone-increasing-digits/description/
题目描述:
给一个数n,要求返回一个最大的数num,使得num<=n,且num从左到右是(非严格)单调递增的。
例如,n=324,
则num为299
基本思路:
可以用搜索实现,但是不是此题的最优解。
通过一些简单的样例分析可以发现,答案往往呈现出x999的模样。
即从某位开始就是连续的9,我们只需要找到这个位置wei即可。
以n=5621为例,
先令num=n,并且转换为字符串便于处理,
从右往左遍历,
i=3时,(2>1),则wei=i=3,同时n[i-1]--,得到临时的num
(其中的'.'代表'9',下同)
num=561.
i=2时,(6>1),则wei=i=2,同时n[i-1]--,得到临时的num
num=55..
i=1时,(5<=5),wei不变,num不变
num=55..
最后,将num从wei(wei=2)处向右的所有字符变为9,即为答案。
参考《代码随想录》中的写法,代码如下:
代码实现:
class Solution
{
public:
int monotoneIncreasingDigits(int n)
{
string s = to_string(n);
int len = s.size();
int wei = len; // 从哪里开始不合理,则后面的全变为'9'
for (int i = len - 1; i > 0; i--) //从后往前遍历
{
if (s[i] < s[i - 1])
{
wei = i;
s[i - 1]--;
}
}
for (int i = wei; i < len; i++)
s[i] = '9';
return stoi(s);
}
};
时间复杂度
O(n)
补充
为什么从右往左遍历而非从左往右遍历,可以简单地从逻辑分析出来:
既然是找最大的num,则优先从数字的低位开始变换,最后得到的结果才会尽可能大。
并且整个过程会非常顺畅,扫描一遍就行。
例如,n=332
如果从左往右进行变化,
则num会先变为num=329,
后2位好不容易符合题意了,但是由于最高位的3与次高位的2不符合大小关系,
因此此时的num是不符合题意的,
而由于采用了从左往右遍历的方式,
导致我们需要从左到右重新扫描一遍,
再得到num=299。
因此会比较麻烦,时间复杂度会更高一些。
所以推荐从右往左遍历。
浙公网安备 33010602011771号