题目:
这次的题和上次返回下一个数字的题目很像。也是对序列找到第一个逆序数字然后处理。这次我依旧采取了相同的办法。
新建了一个栈,然后把元素入栈,找到第一个逆序的元素的时候,往回找到第一个小于当前元素的数。比如33442,就要找到第二个3。然后还设置了一个标识,标识有没有找到逆序数,如果找到了则执行后续操作。4-1然后后几位置9.
但是答案还是更简单,这里我们根本就不需要使用栈,因为只需要找到第一个降序的数字做处理,并且回溯的时候,只需要找到第一个比较小的那个元素的前一个数字即可,该数字减一保持升序,然后后几位全部置9。
C++代码附带测试:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//自己写的复杂废物版
//class Solution {
//public:
// int monotoneIncreasingDigits(int N) {
// string s = to_string(N);//使用to_string转换为字符串
// vector<int> tool;
// tool.push_back((int)s[0]-'0');
// int j = 0;
// int ans = 0;
// int num = 1;
// int last = 0;//剩下多少元素
// int mark = 0;//是否遇到降序
//
// for(int i=1;i<s.length();i++)
// {
// if(j<tool.size()&&s[i]-'0'>=tool[j])
// {
// tool.push_back((int)s[i]-'0');
// j++;
// }
// else{
// last = s.length() - i;
// mark = 1;
// break;
// }
// }
//
// int x = tool[j];
//
// while(j>0&&mark==1&&tool[j-1]==x)
// {
// if(j!=0)
// tool[j] = 9;
// j--;
// }
//
// if(j<tool.size()&&mark==1)
// {
// tool[j] -=1;
// }
//
// for(int i=0;i<last;i++)
// {
// tool.push_back(9);
// }
//
// for(int i=tool.size()-1;i>=0;i--)
// {
// ans += tool[i]*num;
// num *=10;
// }
//
// return ans;
// }
//};
class Solution {
public:
int monotoneIncreasingDigits(int N) {//由于只用找到第一个降序数字,所以可以不使用栈
string strN = to_string(N);
int i = 1;
while (i < strN.length() && strN[i - 1] <= strN[i]) {
i += 1;
}//找到第一个降序数字
if (i < strN.length()) {//如果i没有到数组的尽头
while (i > 0 && strN[i - 1] > strN[i]) {//保证修改后的序列仍然是升序
strN[i - 1] -= 1;
i -= 1;
}
for (i += 1; i < strN.length(); ++i) {//之后全部置9
strN[i] = '9';
}
}
return stoi(strN);//stoi再变回int
}
};
int main()
{
int N =332;
Solution s;
int ans = s.monotoneIncreasingDigits(N);
cout<<ans<<endl;
}