题目描述
解法一:DFS
将 [ 1 , n ] [1, n] [1,n] 的数按照字典序添加到答案,本质上是对一颗节点数量为 n n n,形态类似字典树的多阶树进行遍历
递归树如下:
递归实现:
递归调用栈,会使用栈的空间,对于栈空间的使用取决于递归调用深度
class Solution {
public List<Integer> lexicalOrder(int n) {
List<Integer> res = new ArrayList<>();
dfs(res, n, 0);
return res;
}
private void dfs(List<Integer> list, int n, int val) {
for (int i = 0; i < 10; i++) {
if (i == 0 && val == 0) {
continue ;
}
if (val * 10 + i > n) {
return ;
}
list.add(val * 10 + i);
dfs(list, n, val * 10 + i);
}
}
}
- 时间复杂度:本质上在搜索一棵节点数量为 nn 的多阶树(形态类似于字典树),复杂度为 O ( n ) O(n) O(n)
- 空间复杂度:忽略递归带来的额外空间开销,复杂度为 O ( 1 ) O(1) O(1)
迭代实现:
递归具有额外的空间开销,为了实现严格的 O ( 1 ) O(1) O(1) 空间,需要使用「迭代」来实现
DFS
。
共有 n n n 个数需要被处理,假设当前处理到的数为 n u m b e r number number,根据字典序规则,它的下一个字典序整数对应下面的规则:
-
尝试在 n u m b e r number number 后面附加一个零,即 number × 10 \textit{number} \times 10 number×10,如果 number × 10 ≤ n \textit{number} \times 10 \le n number×10≤n,那么说明 number × 10 \textit{number} \times 10 number×10 是下一个字典序整数;
-
如果 number m o d 10 = 9 \textit{number} \bmod 10 = 9 numbermod10=9 或 number + 1 > n \textit{number} + 1 \gt n number+1>n,那么说明末尾的数位已经搜索完成,退回上一位,即 number = ⌊ number 10 ⌋ \textit{number} = \Big \lfloor \dfrac{\textit{number}}{10} \Big \rfloor number=⌊10number⌋,然后继续判断直到 number m o d 10 ≠ 9 \textit{number} \bmod 10 \ne 9 numbermod10=9 且 number + 1 ≤ n \textit{number} + 1 \le n number+1≤n 为止,那么 number + 1 \textit{number} + 1 number+1 是下一个字典序整数。
public List<Integer> lexicalOrder(int n) {
List<Integer> ret = new ArrayList<Integer>();
int number = 1;
for (int i = 0; i < n; i++) {
ret.add(number);
if (number * 10 <= n) {
number *= 10;
} else {
while (number % 10 == 9 || number + 1 > n) {
number /= 10;
}
number++;
}
}
return ret;
}
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)