簡體   English   中英

給定一個自然數N,找出不大於N的單調非遞減數字的最大數

[英]Given a natural number N, find the largest number not greater than N with monotone nondecreasing digits

給定一個非負整數 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;
        }

    }

您不應該使用任何List因為您可以直接處理號碼的數字。

例子

讓我們考慮一個數字776 這個數字的數字不是單調不減的,因為6 < 7 (每個右邊的數字不能小於它左邊的相鄰數字)。

如果我們最大化數字6並減少其相鄰的7那么我們將得到769 但它的數字不是單調非遞減的。 所以,我們應該減少最左邊的7並最大化67 - 699

算法

  1. 開始從左到右檢查您號碼的數字。
    1. 如果沒有右數字小於其左相鄰數字,則當前數字就是答案。
    2. 如果某個數字d_i大於其右側相鄰數字d_i+1則將最左邊的數字遞減等於d_i 將該數字后面的所有數字設置為9
  2. 打印解決方案

示例代碼

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--;
    }

    // if the leftmost digit is 1 then mark with \0 so that to remove later 
    if (chars[i] == '1') {
        // get rid of this char later to avoid a leading zero
        chars[i] = '\0';
    } else {
        chars[i]--;
    }

    // maximise all the digits to the right of the previous digit
    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);
    }
}

輸入

19

1234

332

12214512

11110

輸出

9

1234

299

11999999

9999

首先復制輸入。 我們將修改此副本以獲得答案。

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(digits) = O(log N)

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 回答。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM