直接对于树的算法操作大多数很经典,比较难的算法是题目中没有给出树结构但是,构造树结构解决能够达到较好的性能
(1)有序问题——类似于二叉搜索树,使用树结构有时候有利于解决一些和顺序相关的问题
(2)带有前缀的序列问题
问题1、 给定一个整数 n, 返回从 1 到 n 的字典顺序。
例子: 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。
分析:这道题可以很容易感觉到数字出现的规律,但是想要总结起来却十分复杂。这显然就是一个带有前缀的有序问题所以可以使用树结构来解决
如上图,每一层都是对上一层作为前缀的有序扩展(这里有序指的是前缀相同时按照原本的字典序从左到右排列)
但是构造这棵树需要花费时间,事实上我们只需要遍历这棵假想的树就行了,不需要真的构建出来
代码如下:
直接对于树的算法操作大多数很经典,比较难的算法是题目中没有给出树结构但是,构造树结构解决能够达到较好的性能
(1)有序问题——类似于二叉搜索树,使用树结构有时候有利于解决一些和顺序相关的问题
(2)带有前缀的序列问题
问题1、 给定一个整数 n, 返回从 1 到 n 的字典顺序。
例子: 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。
分析:这道题可以很容易感觉到数字出现的规律,但是想要总结起来却十分复杂。这显然就是一个带有前缀的有序问题所以可以使用树结构来解决
如上图,每一层都是对上一层作为前缀的有序扩展(这里有序指的是前缀相同时按照原本的字典序从左到右排列)
但是构造这棵树需要花费时间,事实上我们只需要遍历这棵假想的树就行了,不需要真的构建出来
代码如下:
public class LexicographicalNumbers {
public List<Integer> lexicalOrder(int n) {
List<Integer> list = new ArrayList<>();
for(int i = 1;i<=9;i++) {
dfs(i,n,list);//开头前缀不能是0
}
return list;
}
private void dfs(int i, int n, List<Integer> list) {
if(i<=n) {//如果满足范围要求才进行操作
//先根深度遍历
list.add(i);//添加该节点数字到list中去
for(int j = 0;j<=9;j++) {
dfs(j,n,list);//深度优先遍历
}
}
}
}