[LeetCode] 738. Monotone Increasing Digits

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 }

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/14141942.html