【问题标题】:Given a natural number N, find the largest number not greater than N with monotone nondecreasing digits给定一个自然数 N,找出不大于 N 且单调非递减数字的最大数
【发布时间】:2018-07-11 17:02:15
【问题描述】:

给定一个非负整数 N,找出小于或等于 N 且单调不减位数的最大整数。

(回想一下,当且仅当每对相邻数字 x 和 y 满足 x

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

    }

【问题讨论】:

    标签: java algorithm data-structures


    【解决方案1】:

    您不应该使用任何List,因为您可以直接处理您号码的数字。

    示例

    让我们考虑一个数字776。这个数字的位数不是像6 &lt; 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

    【讨论】:

      【解决方案2】:

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

      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)

      【讨论】:

        【解决方案3】:
        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 回答。

        【讨论】:

          猜你喜欢
          • 2015-12-09
          • 2019-07-11
          • 1970-01-01
          • 2012-02-24
          • 2012-01-06
          • 2020-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多