【算法】斐波那契数列vs卡塔兰数列DP

1. 斐波那契数列

公式:

\small f(n) = \left\{\begin{matrix} 1, & n = 0 \\ 1, & n = 1\\ f(n-1) + f(n-2),& otherwise \end{matrix}\right.

应用:爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

class Solution:
    def climbStairs(self, n):
        if n <= 1:
            return 1
        res = [0 for i in range(n+1)]
        res[0] = 1 #0层楼梯不用爬,1种
        res[1] = 1
        for i in range(2, n+1):
            res[i] = res[i-1] + res[i-2]
        return res[-1]

2. 卡塔兰数

公式:

 \small C_n = \sum _{i=1}^{n}C_{i-1} * C_{n-i}

应用:不同二叉搜索树

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

二叉搜索树,左子树节点小于根,右子树节点大于根。递归求解:

res[i]表示有i个节点时,树的种类数。初始化res[i] = 0。

n == 0时,只有一种树,res[0] = 1

n == 1时,当以1为根时,左子树种类数res[0], 右子树种类数res[0], 则res[1] = res[0]*res[0]

n== 2 时,当以1为根时,左子树种类数res[0], 右子树种类数res[1], 则res[2] += res[0]*res[1]

                  当以2为根时,左子树种类数res[1], 右子树种类数res[0],则res[2] += res[1]*res[0]

以此类推。。。

class Solution:
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        #res[i] 指i个数时,二叉搜索树个数
        res = [0 for i in range(n+1)]
        res[0] = 1 #n为0时,个数为1
        for i in range(1, n+1):
            #当n为i时,树的个数为以1~i每个数为根时左子树*右子树
            for j in range(1,i+1):
                res[i] += res[j-1]*res[i-j]
        return res[-1]

应用:不同的二叉搜索树II

class Solution:
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """
        if n < 1:
            return []
        return self.generate( 1, n)
    
    def generate(self,start,end):
        res = []
        if start > end:
            res.append(None)
            return res
        for i in range(start, end+1):
            left = self.generate(start, i-1)
            right = self.generate(i+1,end)
            for l in left:
                for r in right:
                    root = TreeNode(i)
                    root.left = l
                    root.right = r
                    res.append(root)
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值