当前位置 博文首页 > Inmaturity_7的博客:算法练习帖--29--单调递增的数字(Java)
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
(题目来源:力扣(LeetCode))
示例 1:
输入: N = 10
输出: 9
示例 2:
输入: N = 1234
输出: 1234
示例 3:
输入: N = 332
输出: 299
1. 逻辑法(看完官方题解的我,眼泪掉下来)
取到正整数N的位数,从高位向低位遍历,找到"下坡点",本来要正序,要是没有逆序的两个数字说明正整数N符合要求,如果有两个数字逆序,按顺序称为B,C
即B>C,再找到B之前的数字A,此时有两种情况:
1.若A不存在(B已经是最高位),B变为B-1,C变为9
2. 若A存在(也有两种情况):
package com.lxf.test;
public class MonotoneIncreasingDigits {
public static void main(String[] args) {
//1-9 1-9
// 10 9
// 22 22
// 15 15
// 76 69
// 45 45
//131 129
//110 99
//210 199
//1101 999
//3433 3399
//3354 3349
//332 299
System.out.println(monotoneIncreasingDigits(10));
}
public static int monotoneIncreasingDigits(int N) {
//获取正整数N最大的位数maxDigital
int maxDigital=1;
int m=N;
//获取当前位数字的基数(用于截取数字)
int base=1;
while(m/10!=0) {
maxDigital++;
m/=10;
base*=10;
}
//循环位数
int i=maxDigital;
//获取第一位上的数字
int first,second;
second=N/base;
while(i>1) {
//从高位第一位开始往下搜索(第二次直接拿second就好)
first=second;
//从高位第二位开始往下搜索
if(i!=2) {
second=(N%base)/(base/10);
}else {
second=N%10;
}
//当前位数字大于下一位数字开始处理
if(first>second) {
//获取base2,当前前一位数的基数
int base2=base*10;
int j=i+1;
while(j<=maxDigital) {
//first的前一位
int zero=0;
//最高位上的数和其它位上的数计算方式不一样
if(j==maxDigital) {
zero=N/base2;
}else {
zero=N%(base2*10)/base2;
}
//如果zero为最高位,并且最高位和下一位相等直接返回结果就好
if(j==maxDigital&&zero==first) {
return (N/base2)*base2-1;
}
//如果first大于zero,说明first可减去1,first后的全置为9(最大)
if(first>zero) {
return N-N%(base2/10)-1;
}
first=zero;
j++;
base2*=10;
}
return (N/base)*base-1;
}
i--;
base/=10;
}
return N;
}
}
2. 贪心法(官方题解,想法一样,实现不一样)
class Solution {
public int monotoneIncreasingDigits(int N) {
char[] strN = Integer.toString(N).toCharArray();
int i = 1;
//从高位向低位寻找高位数字大于高位下一位的数字
while (i < strN.length && strN[i - 1] <= strN[i]) {
i += 1;
}
//如果这个数字小于strN的长度就处理
if (i < strN.length) {
//从这个位置开始减1,如果减完1大于等于这个位置前一位的数字就不必要继续
//否则这个位置的前一位持续减一
//比如332 第二位大于第三位,首先第二位减一等于2小于第一位,
//所以第一位还要减去1,等于222进入下一步处理
while (i > 0 && strN[i - 1] > strN[i]) {
strN[i - 1] -= 1;
i -= 1;
}
//将最后一次减1的位数字后面所有数字都置为9
//222->299
//如果
for (i += 1; i < strN.length; ++i) {
strN[i] = '9';
}
}
return Integer.parseInt(new String(strN));
}
}
cs