【LeetCode每日一题打卡】386. 字典序排数

167 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。

个人博客链接:bbstudy.net/ (等毕业论文做好后续会完善相关功能)

4.18:字典序排数

LeetCode 386,点击题目可直接跳转至LeetCode

给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。

你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。

示例1:

输入: n = 13
输出: [1,10,11,12,13,2,3,4,5,6,7,8,9]

示例2:

输入: n = 2
输出: [1,2]

提示:

  • 1 <= n <= 5 * 10^4

题解:DFS

题目要求按照字典序返回[1,n]中的所有数字。时间复杂度要求为O(n)O(n),空间复杂度要求为:O(1)O(1)

例如:n=13时,输出为:[1,10,11,12,13,2,3,4,5,6,7,8,9]。

思考能否直接从1开始遍历出第一位数字为1且小于等于n的所有数字;然后再遍历2,3,...9。这样便可在时间复杂度O(n)O(n)条件下实现题目要求。

不难想到dfs可以很好地实现上述思路:

  • 最高位从1到9
  • 次高为从1到9
  • ....

直到遍历完所有的位数。期间如果遍历的数字超过了n则直接结果此轮的dfs。具体代码如下:

C++代码:

class Solution {
public:
    int cnt,num;
    vector<int> ans;
    void dfs(int now,int n){
        if(now>n||cnt>n) return ;
        ++cnt;ans.push_back(now);
        for(int i=0;i<=9;i++){
            dfs(now*10+i,n);
        }
    }
    vector<int> lexicalOrder(int n) {
        cnt=1,num=1;
        for(int i=1;i<=9;i++){
            dfs(i,n);
        }
        return ans;
    }
};

当然将dfs转换为迭代算法同样可以实现,但是此处并没有给出相应代码,读者可以自行思考。