Leetcode算法學習日誌-386 Lexicographical Numbers

Leetcode 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.

題意分析

給定一個數n,將1到n之間的數按照字典順序輸出。

解法分析

首先要搞清楚字典順序的含義,字典順序準則有兩條,第一條是如果一個序列是另一個序列的前部,則短的序列一定在長序列之前,如ab在abc之前,如果兩個序列有對應位不相同,不管兩個序列長短如何,只需要比較第一個不相同字符的前後順序,如134>1245677。本題採用兩種方法來解,一是直接構造法,二是深度優先搜索。

  • 直接構造

由於1一定是第一個元素,所以可以將temp初始化爲1,外層循環按照res的長度進行。對1乘10,得到10,如果沒有超過n,則本輪循環結束,進入下次循環,並把10放入res,多次乘十,直到不能再大,此時判斷temp+1是否超過n,如果超過了,就整體除以10,不然就直接加一,最後判斷是否進位,有進位就把0去掉。C++代碼如下:

class Solution {
public:
    vector<int> lexicalOrder(int n) {
        int temp=1;
        int i;
        vector<int> res(n,1);
        for(i=0;i<n;i++){
            res[i]=temp;//1 should be added,so do this step first
            if(temp*10<=n){//先判斷,之後再賦值
                temp*=10;
            }
            else{
                if((temp+1)>n){//先做判斷,再賦值
                    temp/=10;
                }
                temp++;
                while(temp%10==0)
                    temp/=10;
            }
        }
        return res;
    }
};
  • 深度優先搜索

通過字典序的特點可以看出,如果開頭爲1,則以1位樹根,0-9爲下一層節點,每一個節點又以0-9位子節點,這樣利用深度優先搜索就能得到相應字典順序,對於大於n的情況可以在搜索中剪去。外層循環遍歷1-9作爲開頭數字。C++代碼如下:

class Solution {
private:
    int N;
    vector<int> res;
public:
    void dfs(int k){
        if(k>N)
            return;
        res.push_back(k);
        for(int i=0;i<=9;i++){
            if((10*k+i)>N)
                return ;
            dfs(10*k+i);
        }
    }
    vector<int> lexicalOrder(int n) {
        N=n;
        for(int i=1;i<=9;i++)
            dfs(i);
         return res;
            }
     };




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章