力扣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)
浙公网安备 33010602011771号