以1-N为节点的二叉搜索树的个数和生成对应的二叉搜索树

输入: 3
输出: 5
解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

以1-N为节点的二叉搜索树的个数和生成对应的二叉搜索树_第1张图片

要满足是二叉搜索树,以i为root, 左子树的个数为i-1(比i小的数),右子树的个数为n-i(比i大的数)。

此时如果出现个数为0,表示空树,记作1;只有一个节点,表示只有根的树,也记作1.

f(i)=f(i-1)*f(n-i) (一一组合配对构成整个二叉搜索树)

所以1-n为节点构成的二叉搜索树的个数为:

以1-N为节点的二叉搜索树的个数和生成对应的二叉搜索树_第2张图片

参看代码:

class Solution {
public:
    int numTrees(int n) {
        
        vector dp(n + 1, 0);

        //初始化: 0个节点 和 1个节点
        dp[0] = 1, dp[1] = 1;//空树也是树

        //转换方程: 以i作为root
        for(int i = 2; i <= n; ++ i){
            for(int j = 1; j <= i; ++ j){
                //左子树个数 * 右子树个数
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }

        return dp[n];
    }
};

实际上这个公式推导的出的数被称为卡特兰数(详解请自行百度或google),它的定义为:

 

那么如何生成以上由1-N个节点构成的多个二叉搜索树呢?

思路:先生成以i为root的左子树和右子树集(可采取递归调用的方式),然后根据以上的公式,以i为root的BST的个数=左子树*右子树(分别遍历左右子树集,拼接成BST即可)。

 

参考代码:

/**
 * 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 generateTrees(int n) {
        if(n == 0) return {};
        return generate(1, n);
    }

    vector generate(int start, int end){
        vector res;
        if(start > end){
            res.push_back(NULL);
            return res;
        }

        for(int i = start; i <= end; ++ i){
            //生成左右子树集
            vector l_trees = generate(start, i - 1);
            vector r_trees = generate(i + 1, end);

            //然后拼接成树
            for(auto &l_tree : l_trees){
                for(auto &r_tree : r_trees){
                    TreeNode* root = new TreeNode(i);
                    root->left = l_tree;
                    root->right = r_tree;
                    res.push_back(root);
                }
            }
        }
        return res;
    }

};

以上就是这篇的主要内容,有问题或疑惑请您指出,谢谢!

 

你可能感兴趣的:(leetcode,数据结构)