zoukankan      html  css  js  c++  java
  • [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 题目总结

  • 相关阅读:
    Python3之random模块常用方法
    Go语言学习笔记(九)之数组
    Go语言学习笔记之简单的几个排序
    Go语言学习笔记(八)
    Python3之logging模块
    Go语言学习笔记(六)
    123. Best Time to Buy and Sell Stock III(js)
    122. Best Time to Buy and Sell Stock II(js)
    121. Best Time to Buy and Sell Stock(js)
    120. Triangle(js)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14141942.html
Copyright © 2011-2022 走看看