386. Lexicographical Numbers

Posted apanda009

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了386. Lexicographical Numbers相关的知识,希望对你有一定的参考价值。

Given an integer n, return 1 - n in lexicographical order.

For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].

Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.

 

Solution 1: 

If we look at the order we can find out we just keep adding digit from 0 to 9 to every digit and make it a tree.
Then we visit every node in pre-order. 
       1        2        3    ...
      /\        /\       /   10 ...19  20...29  30...39   ....

public class Solution {
    public List<Integer> lexicalOrder(int n) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        for (int i=1; i<=9; i++) {
            helper(res, i, n);
        }
        return res;
    }
    
    public void helper(ArrayList<Integer> res, int cur, int n) {
        if (cur > n) return;
        res.add(cur);
        for (int i=0; i<=9; i++) {
            helper(res, cur*10+i, n);
        }
    }
}

  

Solution 2: 

O(N) time, O(1) space

The basic idea is to find the next number to add.
Take 45 for example: if the current number is 45, the next one will be 450 (450 == 45 * 10)(if 450 <= n), or 46 (46 == 45 + 1) (if 46 <= n) or 5 (5 == 45 / 10 + 1)(5 is less than 45 so it is for sure less than n).
We should also consider n = 600, and the current number = 499, the next number is 5 because there are all "9"s after "4" in "499" so we should divide 499 by 10 until the last digit is not "9".

 

Note: 第二、三种情况不能合并的原因是:不一定是因为最后一位是9才需要/10,有可能是因为curr+1>n

public List<Integer> lexicalOrder(int n) {
        List<Integer> list = new ArrayList<>(n);
        int curr = 1;
        for (int i = 1; i <= n; i++) {
            list.add(curr);
            if (curr * 10 <= n) {
                curr *= 10;
            } else if (curr % 10 != 9 && curr + 1 <= n) {
                curr++;
            } else {
                while ((curr / 10) % 10 == 9) {
                    curr /= 10;
                }
                curr = curr / 10 + 1;
            }
        }
        return list;
    }

  

以上是关于386. Lexicographical Numbers的主要内容,如果未能解决你的问题,请参考以下文章

386. Lexicographical Numbers

386. Lexicographical Numbers

386. Lexicographical Numbers 把1--n按字典序排序

(Java) LeetCode 386. Lexicographical Numbers —— 字典序排数

386. Lexicographical Numbers 输出1到n之间按lexico排列的数字序列

Swift Playground 错误:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)