leetcode96. 不同的二叉搜索树
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
/ / /
3 2 1 1 3 2
/ /
2 1 2 3
方法:动态规划
思路:
本题看似困难,实际上很简单,可以说跟树结构都没有关系。
我们首先回顾二叉搜索树的定义,二叉搜索树的根节点左边结点比它小,右边结点比它大,且左右结点构成的子树也是二叉搜索树。
如果给了n个结点,那么我们的的根节点可以是n个结点的任意一个,假设为i,那么左结点就只能为[1,i-1]中的某一个了,右结点就位[i,n]中的某一个。由于左右结点也是二叉搜索树,那么如果此时根节点为i,左边可能出现的子树个数即为n=i-1时的答案,右边可能出现子树的个数即为n = n-i时的答案。左右两边的答案相乘,即为i为根节点状况下的二叉搜索树个数;遍历所有的i,都相加,即为n个结点的二叉搜索树总个数。
我们假设dp[i]为1...i为节点组成的二叉搜索树的种数。
那么,对于dp[n]来说,状态转移方程为:
现在考虑边界条件,对于上面的方程,当j=0或j=n-1时,相当于左边/右边子节点为空,此时我们只需考虑另一边的种类数,因此我们将dp[0]=1。
最后的答案为dp[n]。
代码:
class Solution:
def numTrees(self, n: int) -> int:
dp = [0 for _ in range(n+1)]
dp[0] = 1
for i in range(1,n+1):
for j in range(i):
dp[i] += dp[j]*dp[i-1-j]
return dp[n]