LeetCode50天刷题计划第二季(Day 6 — 不同的二叉搜索树 II(15.00-15.50)Day7——不同的二叉搜索树

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

累 想玩

一、题目

不同的二叉搜索树 II

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

示例

示例 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 <= 8

二、思路

这个解法的本质还是一种dfs,带有回溯的操作。
输出的结果是一个列表,其中是所有可能的二叉搜索树的根结点
首先,构造二叉搜索树就是一个递归的过程,将某个结点作为根结点,然后其前和其后的区间再构成另外的二叉搜索树;其次,对于一段区间,如果把所有的结点依次拿出来作为根结点,然后把其所有可能的左子树和右子树依次组合起来,就可以得到所有可能的二叉搜索树
在实现上,每次可以把树的根结点存储在列表中,在遍历中方便连接

三、代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def generateTrees(self, n: int) -> List[Optional[TreeNode]]:
        if(n==0): #n=0时,返回空列表,没有符合要求的树
            return []
        def build_Trees(left,right): #在left和right区间内生成树,返回由这个区间的数字生成树的根结点的集合(列表)
            all_trees=[] #返回的列表
            if(left>right): #返回空,作为叶子结点的标志
                return [None]
            for i in range(left,right+1): #把区间内的每一个值依次用作根结点
                left_trees=build_Trees(left,i-1) #生成其左子树
                right_trees=build_Trees(i+1,right) #生成其右子树
                for l in left_trees:
                    for r in right_trees:  #组合所有左子树和右子树的选择
                        cur_tree=TreeNode(i) #生成根结点
                        cur_tree.left=l
                        cur_tree.right=r #分配左右子树
                        all_trees.append(cur_tree) #加入列表
            return all_trees #返回列表
        res=build_Trees(1,n) #调用函数
        return res

在这里插入图片描述

四、题目

不同的二叉搜索树

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

示例

示例 1:
输入:n = 3
输出:5

示例 2:
输入:n = 1
输出:1

提示

1 <= n <= 19
通过次数301,135提交次数425,649

五、思路

这道题虽然跟上面的描述一样,但因为数据规模扩大了一倍,所以如果仍然用dfs,只是改成计数的话,就会超时。
因此选择用递推的方法(dp,动态规划):
这种方法可以成立的关键是,假设G(n)是长度为n的(连续)序列构成的二叉搜索树的个数 则 G(n)的值与具体数值无关,只与n有关;
因此,而G(n)的递推公式为,用i(1~n所有数依次)当根结点,然后G(i-1)*G(n-i)的和;
初始值:G(0)=1(当做叶子结点标志);G(1)=1;

六、代码

class Solution:
    def numTrees(self, n: int) -> int:    
        #假设G(n)是长度为n的(连续)序列构成的二叉搜索树的个数 则 G(n)的值与具体数值无关,只与n有关
        #而G(n)的递推公式为,用i(1~n所有数依次)当根结点,然后G(i-1)*G(n-i)的和
        #初始值:G(0)=1(当做叶子结点标志);G(1)=1
        G=[1 for x in range(20)]
        for j in range(2,n+1):
            temp=0
            for i in range(1,j+1):
                temp+=G[i-1]*G[j-i]
            G[j]=temp
        return G[n]

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值