生成所有可能的二叉搜索树
前言
对于树问题,利用其递归性质是解题的基础,从下到上生成子树,通过左右子树以笛卡尔积的方式组合成任意子树,这样处理好左右子树和根节点,那么整个树就处理好了。
一、不同的二叉搜索树 II
二、递归生成回溯拼接
package everyday.medium;
import java.util.ArrayList;
import java.util.List;
// 不同的二叉搜索树II
public class GenerateTrees {
/*
target:给定n个节点,生成任意二叉搜索树。
区分划分为左右区间,分别表示左右子树,从下到上生成子树返回并以笛卡尔积的方式拼装,直到主根节点。
*/
public List<TreeNode> generateTrees(int n) {
return generateTrees(1, n);
}
private List<TreeNode> generateTrees(int begin, int end) {
List<TreeNode> ans = new ArrayList<>();
// 递归出口,当begin > end时,返回左右子树集,但其中只有null节点。
if (begin > end) {
ans.add(null);
return ans;
}
// 划分集合并拼装。
// 以每个位置为头节点。
for (int i = begin; i <= end; i++) {
// 得到左右子树所有生成情况。
List<TreeNode> leftNodes = generateTrees(begin, i - 1);
List<TreeNode> rightNodes = generateTrees(i + 1, end);
// 左右子树笛卡尔积进行拼接。
for (TreeNode left : leftNodes) {
for (TreeNode right : rightNodes) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
ans.add(root);
}
}
}
// 返回所有可能的生成树。
return ans;
}
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
}
总结
1)利用好二叉树的递归特征是基本功。
2)处理好了任意一颗子树,就处理好了整个树。
3)树的生成,一半都是从下到上回溯拼接根节点而成。