单调非递减数字

时间:2018-07-11 17:02:16

标签: java algorithm data-structures

给定一个非负整数N,使用单调非递减数字找到小于或等于N的最大数字。

(回想一下,当且仅当每对相邻数字x和y满足x <= y时,整数才具有单调非递减数字。)

示例1: 输入:N = 10 输出:9 范例2: 输入:N = 1234 输出:1234 范例3: 输入:N = 332 输出:299 注意:N是[0,10 ^ 9]范围内的整数。

您好,我正在尝试解决上述问题,并且在整数较大的情况下超出了时间限制。您能告诉我如何优化解决方案吗?谢谢。

代码:

class Solution {
        public int monotoneNondecreasingDigits(int N) {

            int num = N;
            int quot=0,rem=0;
            List<Integer> res = new ArrayList<>();

            while( num>=0 ){
               if( checkMontone(num) )
                   res.add(num);
               if( res.size() == 2 ) 
                   break;
                num -= 1;
            }

            return Collections.max(res);
        }

        public boolean checkMontone(int num ){

            String s = Integer.toString(num);

            for( int i=1;i<s.length();i++ ){
                if( (int)s.charAt(i-1) > (int)s.charAt(i) )
                    return false;
            }
            return true;
        }

    }

3 个答案:

答案 0 :(得分:1)

您不应使用任何List,因为您可以直接处理数字中的数字。这个想法是要找到比前一个左数字Dk大的第一个数字Dk-1(如果从左到右)。之后,Dk-1之后的所有内容都应设置为9以增加数字。但是,它可能不是最大的数字,因为Dk-1可能等于Dk-2,依此类推。这就是为什么找到最左边的数字Dl以使Dl=Dk-1现在可以递减并将其后的其他所有数字都设置为9的原因。

private static void printLargestMonoton(String number) {
    char[] chars = number.toCharArray();
    int i = 0;
    // find a position after which the requirement is violated
    while (i < chars.length - 1) {
        if (chars[i] > chars[i + 1]) {
            break;
        }
        i++;
    }

    // if at the end then the number is already the valid one
    if (i == chars.length - 1) {
        System.out.println(String.valueOf(chars));
        return;

    }

    // find the left most position to decrement
    while (i >= 1 && chars[i - 1] == chars[i]) {
        i--;
    }

    // it can happen only for the leftmost digit so mark it to empty it later
    if (chars[i] == '1') {
        // get rid of this char later to avoid a leading zero
        chars[i] = '\0';
    } else {
        chars[i]--;
    }
    // all the digits to the right must be 9
    for (i = i + 1;i < chars.length; i++) {
        chars[i] = '9';
    }

    System.out.println(String.valueOf(chars).replace("\0",""));
}

public static void main(String[] args) {
    String[] numbers = new String[]{"10", "1234", "332", "12214512", "11110"};

    for (String number : numbers) {
        printLargestMonoton(number);
    }
}

输出

  

9

     

1234

     

299

     

11999999

     

9999

答案 1 :(得分:0)

首先复制输入。我们将修改此副本以获得答案。

1. Look at each pair of adjacent digits of the input (from left to right). 
2. Find the first pair which is decreasing
3. Let d be the left digit of this pair. 
4. Find the first digit in your copy which is equal to d.
5. Decrement this digit by 1 in the copy.
6. Replace each digit to the right of the decremented digit with 9 in the copy.

例如

input:  12214512
output: 11999999

input:  10
output: 09

运行时间O(数字)= O(log N)

答案 2 :(得分:0)

private static String returnLargestMonotonChars(String number) {

    char[] numberAry = number.toCharArray();
    // start from right side of element.
    for (int index = numberAry.length - 1; index > 0; index--) {
        // If current index number is less than previous then decrease previous by 1
        if (numberAry[index - 1] > numberAry[index]) {
            numberAry[index - 1] = numberAry[index - 1] -= 1;
            // After decreasing previous element make all element value = 9
            for (int i = index; i < number.length(); i++) {
                numberAry[i] = '9';
            }
        }
    }

    return String.copyValueOf(numberAry);
}

使用问题中提到的所有内容并通过@Anatolii回答进行了测试。