您当前的位置: 首页 >  搜索

宝哥大数据

暂无认证

  • 0浏览

    0关注

    1029博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

96. 不同的二叉搜索树

宝哥大数据 发布时间:2019-11-13 10:04:32 ,浏览量:0

一、96. 不同的二叉搜索树 1.1、题目描述

在这里插入图片描述

1.2.1、动态规划  算法分析

  给定一个有序序列 1 ... n,为了根据序列构建一棵二叉搜索树。我们可以遍历每个数字 i,将该数字作为树根,1 ... (i-1) 序列将成为左子树,(i+1) ... n 序列将成为右子树。于是,我们可以递归地从子序列构建子树。 在上述方法中,由于根各自不同,每棵二叉树都保证是独特的。

可见,问题可以分解成规模较小的子问题。因此,我们可以存储并复用子问题的解,而不是递归的(也重复的)解决这些子问题,这就是动态规划法。

算法

问题是计算不同二叉搜索树的个数。为此,我们可以定义两个函数:

G(n): 长度为n的序列的不同二叉搜索树个数。

F(i,n): 以**i为根**的不同二叉搜索树个数(1 ≤ i ≤ n)。

可见,

G(n)是我们解决问题需要的函数。

稍后我们将看到, G(n) 可以从F(i,n) 得到,而F(i,n) 又会递归的依赖于G(n)。

首先,根据上一节中的思路,不同的二叉搜索树的总数 G(n),是对遍历所有 i (1 List[TreeNode]: return self.generateSonTrees(1, n) if n else [] # 构建左右子树 def generateSonTrees(self, start: int, end: int) -> List[TreeNode]: if start > end: return [None, ] ans = [] # 选择每个数字作为根节点 for i in range(start, end+1): # 左子树 leftTree = self.generateSonTrees(start, i-1) # 右子树 rightTree = self.generateSonTrees(i+1, end) for lt in leftTree: for rt in rightTree: root = TreeNode(i) root.left = lt root.right = rt ans.append(root) return ans 2.2.2、动态规划(备忘录)

class Solution:
    def __init__(self) -> None:
    	# 备忘录
        self.d = {}

    def generateTrees(self, n: int) -> List[TreeNode]:
        """
            1. dp问题: dp[i] = dp[i - 1]为左子树 * dp[i+1]为右子树
        """
        return self.help(1, n) if n else []

    def help(self, i, j):
        if (i, j) in self.d:
            return self.d[(i, j)]
        ans = []

        # 根节点
        for v in range(i, j + 1): 
            # 递归找到所有的左子树
            for left in self.help(i, v - 1):
                # 递归找到所有的右子树
                for right in self.help(v + 1, j):
                    root = TreeNode(v)
                    root.left, root.right = left, right
                    ans += [root]

        # 将i,j对应的结果存储起来
        self.d[(i, j)] = ans or [None]
        
        return self.d[(i, j)]
关注
打赏
1587549273
查看更多评论
立即登录/注册

微信扫码登录

0.0699s