【Leetcode每日笔记】96. 不同的二叉搜索树(Python)

文章目录

  • 题目
  • 解题思路
    • 动态规划
      • 状态定义
      • 状态转移方程
    • 数学方法
  • 代码

题目

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

示例:

输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
【Leetcode每日笔记】96. 不同的二叉搜索树(Python)_第1张图片

解题思路

动态规划

状态定义

dp[i]表示当前有i个数字时所构成的不同的二叉搜索树的种数

状态转移方程

以3为例,当以1为根,左子树为空,右子树为2和3,那么右子树的结构的种数就是整个树的种数,为1*dp[2],当以2为根,左右子树分别为1,3,即dp[1]*dp[1],当以3为根,右子树为空,左子树为1,2,为dp[2]*1。
递推可得到状态转移方程: d p [ i ] = ∑ 1 i d p [ j − 1 ] ∗ d p [ i − j ] , j ∈ [ 3 , n ] , 且 d p [ 0 ] = 1 , d p [ 1 ] = 1 , d p [ 2 ] = 2 dp[i] = \sum_{1}^{i}dp[j-1]*dp[i-j],j\in[3,n],且dp[0]=1,dp[1]=1,dp[2]=2 dp[i]=1idp[j1]dp[ij],j[3,n],dp[0]=1,dp[1]=1,dp[2]=2

数学方法

卡塔兰数
C 0 = 1 , C n + 1 = 2 ( 2 n + 1 ) n + 2 C n C_0=1,C_{n+1}=\frac{2(2n+1)}{n+2}C_n C0=1,Cn+1=n+22(2n+1)Cn

代码

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [1,1,2] + [0 for _ in range(n-2)]
        if n < 3:
            return dp[n]
        for i in range(3,n+1):
            for j in range(1,i+1):
                dp[i] += dp[j-1]*dp[i-j]
        return dp[-1]
class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        C = 1
        for i in range(0, n):
            C = C * 2*(2*i+1)/(i+2)
        return int(C)

你可能感兴趣的:(LeetCode一周一结,#,动态规划,动态规划,算法,leetcode,二叉树,数学)