从左向右遍历一个数组,通过不断将其中的元素插入树中可以逐步地生成一棵二叉搜索树。给定一个由不同节点组成的二叉搜索树,输出所有可能生成此树的数组。
数组中的节点只需要满足 每一个节点都必须排在它的子孙结点前面。
示例:
给定如下二叉树
2
/ \
1 3
返回:
[
[2,1,3],
[2,3,1]
]
分析:
方法:BFS + DFS + 回溯
因为每一个节点只需要排在子孙节点前面,那么它同一层的节点排在该节点的哪都无所谓,我们可以利用 深度(DFS) 和 广度遍历(BFS) 结合的方式来解这道题,深度保证节点排在子孙节点前,广度保证同层节点的位置。
每进行一次广度遍历,我们就将该节点进行深度遍历,每进行一次深度遍历,我们就将该节点进行广度遍历,当节点为空时,我们 回溯 到上一个节点,继续遍历下一个节点,直到所有节点遍历完成。
广度遍历时,由于同层节点可能在前面也可能在后面,所有我们按节点个数进行遍历,遍历一个删除一个,深度遍历完成后再复原该节点,然后继续遍历下一个节点。
时间复杂度呈指数级别,没有讨论意义。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//创建总结果集合
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> BSTSequences(TreeNode root) {
//创建集合
List<Integer> list = new ArrayList<>();
//节点为空
if(root == null){
res.add(list);
return res;
}
//创建队列
List<TreeNode> queue = new ArrayList<>();
//添加节点
queue.add(root);
//遍历
dfs(list, queue);
return res;
}
public void dfs(List<Integer> list, List<TreeNode> queue){
//队列为空,添加集合到总集合中
if(queue.isEmpty()){
res.add(new ArrayList<>(list));
return;
}
//复制该队列
List<TreeNode> copyQueue = new ArrayList<>(queue);
//广度遍历
for(int i = queue.size()-1; i > -1; --i){
//获取删除当前位置节点
TreeNode cur = queue.remove(i);
//添加该节点到集合中
list.add(cur.val);
//添加左右节点
if(cur.left != null){
queue.add(cur.left);
}
if(cur.right != null){
queue.add(cur.right);
}
//深度遍历
dfs(list, queue);
//回溯
list.remove(list.size()-1);
queue = new ArrayList<>(copyQueue);
}
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bst-sequences-lcci