LeetCode95题: 不同的二叉搜索树 II

题目链接

https://leetcode-cn.com/problems/unique-binary-search-trees-ii/

解题思路

分治思想:分治算法是把原问题分解为若干个子问题,自顶向下求解子问题,合并子问题的解,从而得到原问题的解。
原问题的拆分过程比较容易,一般就是缩小题目给定的数据范围,主要是子问题的合并过程需要好好体会。
此题需要使用BST的性质来进行原问题拆分,原问题需要得到所有可能的BST的根节点组成的List
(1)给定数据为[1,n],那么最终的List为root为1的时候所有可能的BST+root为2的时候所有可能的BST+root为3的时候所有可能的BST+.....
(2)更一般的情况,当root为node_i的时候,能够产生的BST数目是root左侧BST数目*root右侧BST数目,即一种任意组合问题。
(3)分治的最小子问题就是给定的数据长度为1,则直接返回一个List(只包含一个当前的根节点)
(4)核心过程是所有子问题的拼接过程。

思考

分治思想的合并子问题解的过程,实质上是在递归的过程中使用一些存储结构进行存储,注意不要陷入具体的递归细节。

代码

public class _95_generateTrees {
    public List<TreeNode> generateTrees(int n) {
        return generateTree(1,n);
    }
    public List<TreeNode> generateTree(int begin, int end){
        //存储结果: ans保存了begin至end的所有可能的BST根节点
        List<TreeNode> ans = new ArrayList<TreeNode>();

        //递归出口
        if (begin>end) {ans.add(null); return ans;}
        if (begin==end) {ans.add(new TreeNode(begin));return ans;}

        //递归入口
        for (int node_i=begin;node_i<=end;node_i++){
            //获取所有可能形状的左子树根(BST中root左侧的节点值全部小于root)
            List<TreeNode> ans_left=generateTree(begin,node_i-1);
            //获取所有可能形状的右子树根(BST中root右侧的节点值全部大于root)
            List<TreeNode> ans_right=generateTree(node_i+1,end);
            //与node_i组合所有可能的左右子树
            for (TreeNode node_left: ans_left) {
                for (TreeNode node_right : ans_right) {
                    TreeNode root = new TreeNode(node_i);
                    root.left = node_left;
                    root.right = node_right;
                    //将此种可能的BST根节点加入ans
                    ans.add(root);
                }
            }
        }
        return ans;
    }
}
posted @ 2022-01-19 15:52  mirage_mc  阅读(21)  评论(0编辑  收藏  举报