leetcode树之不同的二叉搜索树

96、不同的二叉搜索树

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

示例1:

输入:n = 3
输出:5

示例2:

输入:n = 1
输出:1

思路:

一个树是由左子树 + 根节点 + 右子树构成,那么这道题就可以分解为从1~n每个节点作为根节点的二叉树总数之和,那么也就是需要知道如果以某一个节点为根,那么它的搜索树的种树是多少。

假设我们取第i个结点作为根节点,那么左侧就应该又i-1个结点,右侧有n-i个结点,那么我们可以假设i个结点构成的子树种树为G(i)

那么取第i个结点作为根节点的种树,应该是左子树的数目 * 右子树的数目


G ( i − 1 ) ∗ G ( n − i ) G(i-1) * G(n-i) G(i1)G(ni)
那么对于n个几点的种树
G ( n ) = G ( 0 ) ∗ G ( n − 1 ) + . . . + G ( i − 1 ) ∗ G ( n − i ) + . . . + G ( n − 1 ) ∗ G ( 0 ) G(n) = G(0) * G(n-1) + ... + G(i-1) * G(n-i) + ... + G(n-1) * G(0) G(n)=G(0)G(n1)+...+G(i1)G(ni)+...+G(n1)G(0)
此时我们只需要迭代计算出G(0)到G(n-1)的值即可,该公式也叫卡特兰数

代码:

class Solution:
    def numTrees(self, n: int) -> int:
        G = [0] * (n + 1)
        G[0] = 1
        G[1] = 1
        for i in range(2, n + 1):
            for j in range(1, i + 1):
                G[i] += G[j - 1] * G[ i - j]
        return G[n]
95、不同的二叉搜索树2

给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。

示例1:

输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]

示例2:

输入:n = 1
输出:[[1]]

思路:

这道题可以用回溯的方法来做,我们可以不同的以从1到n之间每个节点都作为顶点的情况,然后拼接左子树和右子树就行

class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
      	# 这里也可以做一下缓存,避免重复计算
      	# cache = {}
        def generage(start, end):
          	# 这里如果根节点没有左子节点,或者没有右子结点,则返回包含一个空节点的数组
            if start > end: return [None]
            trees = []
            # 遍历,使每个结点都作为根节点的情况
            for i in range(start, end+1):
              	# 得到左子树和右子树的可能情况
                left_trees = generage(start, i-1)
                # 使用缓存情况下
                # if (start, i-1) in cache:
                #    left_trees = cache[(start, i-1)]
                # else:
                #    left_trees = generage(start, i-1)
                #    cache[(start, i-1)] = left_trees
                right_trees = generage(i+1, end)
                # 遍历左右子树笛卡尔积
                for l in left_trees:
                    for r in right_trees:
                        cur_tree = TreeNode(i)
                        cur_tree.left = l
                        cur_tree.right = r
                        trees.append(cur_tree)
            return trees

        if not n: return []
        return generage(1, n)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溪语流沙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值