95 不同的二叉搜索树 II

本文介绍了一种使用递归方法生成由1至n为节点的所有可能二叉搜索树的方法。通过对1到n的数字选择一个作为根节点,将数组分割成左右两部分,利用递归生成左右子树并组合成完整的树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。

示例:
输入:3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]

解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
在这里插入图片描述
提示:
0 <= n <= 8

方法1:递归
主要思路:
(1)根据二叉搜索树的特性,其左边的结点小于根节点,右边的结点大于根节点,则对于 1到 n的数字,选择一个数字作为根节点, 则将原来的数组分割成了左右两个部分,而这两部分可以自己通过这个过程生成其自己的树的组成;
(2)当获得左右两部分的组成之后,就可以将左侧的组成作为根节点的左子树,右侧的组成作为根节点的右子树,生成该节点的所有树;
(3)然后换下一个结点重复上述递归步骤;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:

    vector<TreeNode*> helper(int begin,int end){
    	//范围内没有结点,返回空指针组成
        if(begin>end)
            return {nullptr};
        vector<TreeNode*> all_trees;//存储当前范围内所有结点可以生成的树
        //以该范围内各个结点作为根节点,来生成树的组合
        for(int i=begin;i<=end;++i){
        	//当前结点的左侧部分结点生成的所有树的组合
            vector<TreeNode*>left_trees= helper(begin,i-1);
            //当前结点的右侧部分结点生成的所有树的组合
            vector<TreeNode*>right_trees= helper(i+1,end);
			//将左右两侧生成的树,作为当前结点的左右子树来生成当前结点的所有可能的树
            for(TreeNode*& left_side:left_trees){
                for(TreeNode*& right_side:right_trees){
                    TreeNode* cur_root=new TreeNode(i);
                    cur_root->left=left_side;
                    cur_root->right=right_side;
                    all_trees.emplace_back(cur_root);//将其中的一种树压入结果中
                }
            }
        }

        return all_trees;
    }

    vector<TreeNode*> generateTrees(int n) {
    	//处理特殊的情形
        if(n==0)
            return {};
        //递归生成子树
        return helper(1,n);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值