给定一个非负整数N,使用单调非递减数字找到小于或等于N的最大数字。
(回想一下,当且仅当每对相邻数字x和y满足x <= y时,整数才具有单调非递减数字。)
示例1: 输入:N = 10 输出:9 范例2: 输入:N = 1234 输出:1234 范例3: 输入:N = 332 输出:299 注意:N是[0,10 ^ 9]范围内的整数。
您好,我正在尝试解决上述问题,并且在整数较大的情况下超出了时间限制。您能告诉我如何优化解决方案吗?谢谢。
代码:
class Solution {
public int monotoneNondecreasingDigits(int N) {
int num = N;
int quot=0,rem=0;
List<Integer> res = new ArrayList<>();
while( num>=0 ){
if( checkMontone(num) )
res.add(num);
if( res.size() == 2 )
break;
num -= 1;
}
return Collections.max(res);
}
public boolean checkMontone(int num ){
String s = Integer.toString(num);
for( int i=1;i<s.length();i++ ){
if( (int)s.charAt(i-1) > (int)s.charAt(i) )
return false;
}
return true;
}
}
答案 0 :(得分:1)
您不应使用任何List
,因为您可以直接处理数字中的数字。这个想法是要找到比前一个左数字Dk
大的第一个数字Dk-1
(如果从左到右)。之后,Dk-1
之后的所有内容都应设置为9
以增加数字。但是,它可能不是最大的数字,因为Dk-1
可能等于Dk-2
,依此类推。这就是为什么找到最左边的数字Dl
以使Dl=Dk-1
现在可以递减并将其后的其他所有数字都设置为9
的原因。
private static void printLargestMonoton(String number) {
char[] chars = number.toCharArray();
int i = 0;
// find a position after which the requirement is violated
while (i < chars.length - 1) {
if (chars[i] > chars[i + 1]) {
break;
}
i++;
}
// if at the end then the number is already the valid one
if (i == chars.length - 1) {
System.out.println(String.valueOf(chars));
return;
}
// find the left most position to decrement
while (i >= 1 && chars[i - 1] == chars[i]) {
i--;
}
// it can happen only for the leftmost digit so mark it to empty it later
if (chars[i] == '1') {
// get rid of this char later to avoid a leading zero
chars[i] = '\0';
} else {
chars[i]--;
}
// all the digits to the right must be 9
for (i = i + 1;i < chars.length; i++) {
chars[i] = '9';
}
System.out.println(String.valueOf(chars).replace("\0",""));
}
public static void main(String[] args) {
String[] numbers = new String[]{"10", "1234", "332", "12214512", "11110"};
for (String number : numbers) {
printLargestMonoton(number);
}
}
输出
9
1234
299
11999999
9999
答案 1 :(得分:0)
首先复制输入。我们将修改此副本以获得答案。
1. Look at each pair of adjacent digits of the input (from left to right).
2. Find the first pair which is decreasing
3. Let d be the left digit of this pair.
4. Find the first digit in your copy which is equal to d.
5. Decrement this digit by 1 in the copy.
6. Replace each digit to the right of the decremented digit with 9 in the copy.
例如
input: 12214512
output: 11999999
input: 10
output: 09
运行时间O(数字)= O(log N)
答案 2 :(得分:0)
private static String returnLargestMonotonChars(String number) {
char[] numberAry = number.toCharArray();
// start from right side of element.
for (int index = numberAry.length - 1; index > 0; index--) {
// If current index number is less than previous then decrease previous by 1
if (numberAry[index - 1] > numberAry[index]) {
numberAry[index - 1] = numberAry[index - 1] -= 1;
// After decreasing previous element make all element value = 9
for (int i = index; i < number.length(); i++) {
numberAry[i] = '9';
}
}
}
return String.copyValueOf(numberAry);
}
使用问题中提到的所有内容并通过@Anatolii回答进行了测试。