给定一个非负整数
N
,找出小于或等于N
的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。(当且仅当每个相邻位数上的数字
x
和y
满足x <= y
时,我们称这个整数是单调递增的。)示例 1:
输入: N = 10 输出: 9
1、暴力法(超时)
public int monotoneIncreasingDigits(int N)
{
while (N > 0)
{
if (isIncrease(N))
return N;
N--;
}
return 0;
}
// 判断a各个位上的数字是否单调递增
boolean isIncrease(int a)
{
int c = 0;
int b = a % 10;
a /= 10;
while (a != 0)
{
c = a % 10;
a /= 10;
if (b < c) // 不满足x<=y
return false;
b = c;
}
return true;
}
2、贪心法
用数组作为辅助存储空间,遍历数组,一旦遇到后一位比前一位小的数字,break, 并把后面的位数都变成9, 同时将
现在的位置上-1,(注意0时的特殊情况)。如果遍历完成,则返回该数字。
public int monotoneIncreasingDigits(int N)
{
if(N < 10)
return N;
int[] dp = new int[10]; // 存储每一位数字
int i = 0;
while (N != 0)
{
dp[i++] = N % 10; // 数组里倒着放元素
N /= 10;
}
int m = dp[i-1];
for (int j=i-1; j>0; j--)
{
if (dp[j] <= dp[j-1]) // 单调递增
continue;
else
{
// 贪婪策略
for (int a=j-1; a>=0; a--)
dp[a] = 9;
dp[j] -= 1;
j = i;
}
}
int num = dp[i-1];
// 将dp数组转换成整数
for (int k=i-2; k>=0; k--)
{
num *= 10;
num += dp[k];
}
return num;
}