1.题目描述
字典序排数
给你一个整数 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]
2.思路
2.1 代码
给定一个数,按字典序对排列比该数小的数字,即1,10,11,12,13,2…… 从这里可以看出这其实是一个树形结构,如下图所示
采用深度优先搜索思想进行解答,图中仅每一层树有 1 到 9 共九个节点,当我们遍历到每个节点时,用上一个节点的值从 0 到 9 进行拼接,当拼接后的值比 n 大时,推出当前循环,返回上一层继续往下拼接。使用一个递归函数进行处理,传入参数为当前数 curr 和给定的数字 n ,当传入参数 curr 大于 n 时,直接返回,否则将 curr 加入结果列表中,并从 0 开始与 curr 进行拼接,拼接使用 curr*10+i 计算,当拼接后的数字大于 n 时,结束当前循环,否则将拼接后的数字作为 curr 传入递归函数中。代码如下:
class Solution {
public List<Integer> ans = new ArrayList<>();
public List<Integer> lexicalOrder(int n) {
for (int i = 1; i < 10; i++) {
process(i, n);
}
return ans;
}
public void process(int curr, int n) {
if (curr > n) {
return;
}
ans.add(curr);
for (int i = 0; i < 10; i++) {
int num = curr * 10 + i;
if (num > n) {
break;
}
process(num, n);
}
}
}
2.2 测试结果
通过测试
3.总结
- 使用深度优先思想进行解答
- 将题目转换为树形结构思想,除第一层从 1 到 9,下面每一层均从 0 到 9 进行拼接
- 由于每一次递归的循环中进行拼接,因此退出循环后不需要进行状态还原