【Lintcode】1267. Lexicographical Numbers

記錄演算法發表於2020-12-26

題目地址:

https://www.lintcode.com/problem/lexicographical-numbers/description

給定一個正整數 n n n,返回 1 ∼ n 1\sim n 1n的所有數,按字典序排序。

思路是DFS。DFS天生適合字典序。遞迴第一層是從 1 ∼ 9 1\sim 9 19遍歷,每遍歷到一個數就進入下一層遞迴,第二層從 0 ∼ 9 0\sim 9 09,接在第一層的數後面。例如第一層遍歷到 1 1 1,如果 n < 100 n<100 n<100,進入第二層的時候得到 10 , 11 , 12 , . . . 10,11,12,... 10,11,12,...恰好是字典序緊接著的後面的若干數;如果 n ≥ 100 n\ge 100 n100,則遍歷到 10 10 10的時候又要進入下一層遞迴,得到 100 , 101 , . . . 100,101,... 100,101,...。如果遍歷到大於 n n n的數的時候就返回上一層遞迴。遞迴的順序訪問的數就是字典序。但是要注意 0 0 0不要加入答案裡。程式碼如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    /**
     * @param n: an integer
     * @return: 1 - n in lexicographical order
     */
    public List<Integer> lexicalOrder(int n) {
        // write your code here
        List<Integer> res = new ArrayList<>();
        dfs(0, n, true, res);
        return res;
    }
    
    private void dfs(int cur, int n, boolean start, List<Integer> res) {
    	// 大於n了就返回上一層遞迴
        if (cur > n) {
            return;
        }
        
        // 0要排除掉
        if (cur != 0) {
            res.add(cur);
        }
        
        // 如果是遞迴第一層,則從1開始迴圈,否則從0開始
        for (int i = start ? 1 : 0; i <= 9; i++) {
            dfs(cur * 10 + i, n, false, res);
        }
    }
}

時間複雜度 O ( n ) O(n) O(n),空間 O ( log ⁡ n ) O(\log n) O(logn)

相關文章