Given a non-negative integer N
, find the largest number that is less than or equal to N
with monotone increasing digits.
(Recall that an integer has monotone increasing digits if and only if each pair of adjacent digits x
and y
satisfy x <= y
.)
Example 1:
Input: N = 10 Output: 9
Example 2:
Input: N = 1234 Output: 1234
Example 3:
Input: N = 332 Output: 299
Note: N
is an integer in the range [0, 10^9]
.
单调递增的数字。
给定一个非负整数 N,找出小于或等于 N 的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。
(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/monotone-increasing-digits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意不难理解。这里我提供两种思路,一种是贪心,一种是类似单调栈的做法。
首先是贪心。既然最后需要拼接起来的数字需要从左往右单调增或者起码不递减,那么我们用一个指针从左往右扫描这个数字的每一个digit,看到底在什么地方会找到那个单调增的顶点,同时我们需要记录一下这个顶点之前的一个数字,因为这个数字是不会被改动的,需要被改动的范围是从顶点那个数字往后。注意代码中的max实际是在记录顶点之前的那个数字的位置。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int monotoneIncreasingDigits(int N) { 3 char[] array = String.valueOf(N).toCharArray(); 4 int max = -1; 5 int index = -1; 6 /* 两种case 7 n = 1234321 8 res = 1233999 9 10 n = 2333332 11 res = 2299999 12 */ 13 for (int i = 0; i < array.length - 1; i++) { 14 if (max < array[i]) { 15 max = array[i]; 16 index = i; 17 } 18 if (array[i] > array[i + 1]) { 19 array[index] -= 1; 20 for (int j = index + 1; j < array.length; j++) { 21 array[j] = '9'; 22 } 23 break; 24 } 25 } 26 return Integer.parseInt(new String(array)); 27 } 28 }
其次是类似单调栈的做法。我个人觉得这个做法只是利用到了单调栈的思路,在具体实现上并没有类似单调栈那样为了维持单调性而pop元素出来的情况。我们从右往左遍历这个数字的每一个digit,如果当前的数字cur <= stack.peek()我们则把cur入栈(说明数字从右往左是递减的/从左往右是递增的);反之我们看一下当前stack的size并清空stack,把清空的digit用9补足。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int monotoneIncreasingDigits(int N) { 3 String num = String.valueOf(N); 4 char[] arr = num.toCharArray(); 5 int len = arr.length; 6 Stack<Integer> stack = new Stack<>(); 7 stack.push(arr[len - 1] - '0'); 8 for (int i = arr.length - 2; i >= 0; i--) { 9 int cur = arr[i] - '0'; 10 if (cur <= stack.peek()) { 11 stack.push(cur); 12 } else { 13 int count = stack.size(); 14 stack.clear(); 15 for (int j = 0; j < count; j++) { 16 stack.push(9); 17 } 18 stack.push(Math.max(0, cur - 1)); 19 } 20 } 21 int res = 0; 22 while (!stack.isEmpty()) { 23 res = 10 * res + stack.pop(); 24 } 25 return res; 26 } 27 }