class Solution:
def monotoneIncreasingDigits(self, n: int) -> int:
digits = list(str(n))
mark = len(digits)
for i in range(len(digits)-1, 0, -1):
if digits[i] < digits[i-1]:
digits[i-1] = str(int(digits[i-1]) - 1)
mark = i
for i in range(mark, len(digits)):
digits[i] = '9'
return int(''.join(digits))
class Solution {
public:
int monotoneIncreasingDigits(int n) {
string digits = to_string(n);
int mark = digits.size();
for (int i = digits.size() - 1; i > 0; --i) {
if (digits[i] < digits[i - 1]) {
digits[i - 1]--;
mark = i;
}
}
for (int i = mark; i < digits.size(); ++i) {
digits[i] = '9';
}
return stoi(digits);
}
};
class Solution {
public int monotoneIncreasingDigits(int n) {
char[] digits = Integer.toString(n).toCharArray();
int mark = digits.length;
for (int i = digits.length - 1; i > 0; i--) {
if (digits[i] < digits[i - 1]) {
digits[i - 1]--;
mark = i;
}
}
for (int i = mark; i < digits.length; i++) {
digits[i] = '9';
}
return Integer.parseInt(new String(digits));
}
}
var monotoneIncreasingDigits = function(n) {
let digits = n.toString().split('');
let mark = digits.length;
for (let i = digits.length - 1; i > 0; i--) {
if (digits[i] < digits[i - 1]) {
digits[i - 1] = (parseInt(digits[i - 1]) - 1).toString();
mark = i;
}
}
for (let i = mark; i < digits.length; i++) {
digits[i] = '9';
}
return parseInt(digits.join(''));
};
You are given a non-negative integer n
. Your task is to find the largest number less than or equal to n
such that its digits are in monotone increasing order, meaning each digit is less than or equal to the digit that follows it.
For example, if n = 332
, the answer should be 299
, because 299
is the largest number less than or equal to 332
whose digits are in increasing order.
Constraints:
n
≤ 109
At first, you might consider checking every number from n
down to 0 to see if its digits are monotone increasing. However, this would be extremely inefficient for large values of n
.
Instead, let's analyze what it means for a number to have monotone increasing digits. For any given digit, as long as it is not greater than the digit to its right, the number is still valid. But if a digit is greater than the one after it, we need to "fix" this to maintain the monotone property.
The key insight is that when we find a digit that breaks the rule (i.e., it's larger than the next digit), we should decrease this digit by 1 and set all digits to its right to 9. This ensures we get the largest possible number less than or equal to n
that is monotone increasing.
This approach efficiently finds the correct answer in a single pass from right to left, and another to fill the trailing digits.
Let's walk through the example where n = 332
:
299
At each step, we ensure the digits to the left are not greater than those to the right, and by setting trailing digits to 9, we keep the result as large as possible.
n
down to 0 would take O(n * d), where d
is the number of digits. This is infeasible for large n
.
d
is the number of digits (at most 10 for n ≤ 10^9
).
The problem asks for the largest number less than or equal to n
with digits in monotone increasing order. By scanning the digits from right to left and fixing any violations by decrementing and setting trailing digits to 9, we can efficiently find the answer in linear time relative to the number of digits. The solution is elegant because it leverages the structure of the problem and avoids brute-force enumeration.