• [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 题目总结

  • 相关阅读:
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
    一手遮天 Android
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14141942.html
Copyright © 2020-2023  润新知