想了解更多数据结构以及算法题,可以关注微信公众号“数据结构和算法”,每天一题为你精彩解答。也可以扫描下面的二维码关注
给定一个整数 n, 返回从 1 到 n 的字典顺序。
例如,
给定 n =13,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。
请尽可能的优化算法的时间复杂度和空间复杂度。输入的数据 n 小于等于 5,000,000。
public List<Integer> lexicalOrder(int n) {
List<Integer> res = new ArrayList<>();
for (int i = 1; i < 10; ++i) {
dfs(i, n, res);
}
return res;
}
public void dfs(int cur, int n, List<Integer> res) {
if (cur > n)
return;
res.add(cur);
for (int i = 0; i < 10; ++i) {
dfs(10 * cur + i, n, res);
}
}
解这题之前实现要明白什么是字典序,其实就是类似于字典一样,根据字母的顺序进行排列,我们先来看下面的图
我们可以把它看成有9棵树,每棵树的根节点的值分别是从1到9,并且每棵树都有10个子节点,并且每个子节点又会有10个子节点……
1,代码3到5行分别遍历这9棵树。
2,方法dfs对每棵树执行dfs(深度优先搜索)
我们还可以把递归改为非递归的方式,代码如下
public List<Integer> lexicalOrder(int n) {
List<Integer> ans = new ArrayList<>(n);
int curr = 1;
for (int i = 1; i <= n; ++i) {
ans.add(curr);
if (curr * 10 <= n) {
curr *= 10;
} else {
while (curr % 10 == 9 || curr == n)
curr /= 10;
curr++;
}
}
return ans;
}