Java&C++题解与拓展——leetcode386.字典序排数【么的新知识】

116 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

每日一题做题记录,参考官方和三叶的题解

题目要求

image.png

【前段时间刚做过类似的更难的一道——leetcode440.字典序的第K小数字【字典序学习】,有简单介绍字典序】

思路一:DFS之递归

字典序想到构建字典树进行DFS遍历,对于当前层的每一个节点curcur依次遍历其子节点cur×10+ii[0,9]cur\times10+i,i\in [0,9],即修改每个数字的末位。第一层为[19][1\sim 9](首位)。

Java

class Solution {
    List<Integer> res = new ArrayList<>();
    int lim;
    public List<Integer> lexicalOrder(int n) {
        lim = n;
        for(int i = 1; i <= 9; i++) //首位搜索
            dfs(i);
        return res;
    }

    void dfs(int cur) {
        if(cur > lim)
            return;
        res.add(cur);
        for(int i = 0; i <= 9; i++) //末位搜索
            dfs(cur * 10 + i);
    }
}
  • 时间复杂度:O(n)O(n),搜索nn个节点的树
  • 空间复杂度:O(1)O(1),忽略递归的额外开销

C++

class Solution {
private:
    vector<int> res;
    int lim;
    void dfs(int cur) {
        if(cur > lim)
            return;
        res.push_back(cur);
        for(int i = 0; i <= 9; i++) //末位搜索
            dfs(cur * 10 + i);
    }
public:
    vector<int> lexicalOrder(int n) {
        lim = n;
        for(int i = 1; i <= 9; i++) //首位搜索
            dfs(i);
        return res;
    }
};
  • 时间复杂度:O(n)O(n),搜索nn个节点的树
  • 空间复杂度:O(1)O(1),忽略递归的额外开销

思路二:DFS之迭代

递归存在额外的空间开销,所以将其改为迭代。

思路大体一致,注意判断边界条件,超过限制值注意回退,不要直接丢了这一支。

Java

class Solution {
    public List<Integer> lexicalOrder(int n) {
        List<Integer> res = new ArrayList<>();
        for(int i = 0, j = 1; i < n; i++) { //首位搜索
            res.add(j);
            if(j * 10 <= n) //添0
                j *= 10;
            else {
                while(j % 10 == 9 || j + 1 > n) //超了回退
                    j /= 10;
                j++; //末位搜索
            }
        }
        return res;
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

C++

class Solution {
public:
    vector<int> lexicalOrder(int n) {
        vector<int> res;
        for(int i = 0, j = 1; i < n; i++) { //首位搜索
            res.push_back(j);
            if(j * 10 <= n) //添0
                j *= 10;
            else {
                while(j % 10 == 9 || j + 1 > n) //超了回退
                    j /= 10;
                j++; //末位搜索
            }
        }
        return res;
    }
};
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

总结

算是最近最有意思的题了,但是之前做过字典序,所以很快就有思路,也不太称得上中等难度。

对递归和迭代来回转换的思路方式逐渐熟悉起来。


欢迎指正与讨论!