力扣96. 不同的二叉搜索树

题目来源(力扣):

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

题目描述:

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

基本思路:

一棵二叉搜索树可以拆分为头结点、左子树、右子树。
对于一棵由i个节点构成的二叉搜索树,
以1为头结点的二叉搜索数的数量=左子树有0个元素的二叉搜索树的数量×右子树有(i-1)个元素的二叉搜索数的数量。
以2为头结点的二叉搜索数的数量=左子树有1个元素的二叉搜索树的数量×右子树有(i-2)个元素的二叉搜索数的数量。
以3为头结点的二叉搜索数的数量=左子树有2个元素的二叉搜索树的数量×右子树有(i-3)个元素的二叉搜索数的数量。
……
以(i-1)为头结点的二叉搜索数的数量=左子树有(i-2)个元素的二叉搜索树的数量×右子树有1个元素的二叉搜索数的数量。
以i为头结点的二叉搜索数的数量=左子树有(i-1)个元素的二叉搜索树的数量×右子树有0个元素的二叉搜索数的数量。

因此,令dp[i]表示由1~i结点组成的二叉搜索数的个数,

dp[i]
=以1为头结点的二叉搜索数的数量+以2为头结点的二叉搜索数的数量+以3为头结点的二叉搜索数的数量+……+以i为头结点的二叉搜索数的数量
=dp[0]*dp[i-1]+dp[1]*dp[i-2]+……+dp[i-1]*dp[1].

代码实现:

class Solution {
public:
    int numTrees(int n) {
        // 1.确定dp数组及其含义
        vector<int> dp(n + 1); // dp[i]表示以1~i结点组成的二叉搜索数的个数

        // 2.确定递推公式
        // dp[i]=以1为头结点的二叉搜索数的数量+以2为头结点的二叉搜索树的数量+...+以i为头结点的二叉搜索树的数量
        // dp[i]=dp[0]*dp[i-1]+dp[1]*dp[i-2]+...+dp[i-1]*dp[1]

        // 3.初始化
        dp[0] = dp[1] = 1;

        // 4.确定递推顺序
        // 从小到大
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j < i; j++)
                dp[i] += dp[j] * dp[i - j - 1];
        }

        // 5.打印dp数组以确定是否符合预期
        //  for(int i=0;i<=n;i++)
        //      cout<<dp[i]<<" ";
        //  cout<<endl;

        return dp[n];
    }
};

时间复杂度

O(n^2)

posted @ 2024-12-09 11:11  HB_Computer  阅读(39)  评论(0)    收藏  举报