LeetCode--95. 不同的二叉树搜索Ⅱ(动态规划)

不同的二叉树搜索Ⅱ(动态规划)

1. 题目描述

难度:中等
在这里插入图片描述

2. 题目分析

这道题目是LeetCode96题.不同的二叉树搜索的进阶版,动态规划的思路还是不变的,但是难度提升就在于96题要求我们只需要输出组合的数目,而95题需要我们将所有的树的组合输出。

  • 动态规划
    根据96题,我们得到的动态转移方程为:
dp[i] = dp[i] + dp[i-1]*dp[1] +dp[i-2]*dp[2] + ...+dp[1]*dp[i-1]+dp[i]

其实这一题动态转移方程式没有变,我们只需要更改dp的定义即可,在96题中,我们的dp[i]是存放前i个整数的有可能的组合数目,这一题我们dp[i]是存放的是一个列表,列表存放的是所有可能的二叉搜索树的根节点。这里有几个问题需要注意:

  • 在前i个整数范围内,当根节点为1时
    此时以1为根节点的数的左子树肯定为None
  • 在前i个整数范围内,当根节点为 i 时
    此时以i为根节点的右子树肯定为None
  • 在前i个整数范围内,当根节点在1~i之间时
    以 i = 6 为例,nums = [1, 2, 3, 4, 5, 6], 当以3为跟根节点是,左子树的可能组合与dp[2]移植,但是虽然右子树的组合数与dp[3]一致,但是dp[3]里是[1, 2, 3]构成的组合,并不是[4, 5, 6],所以我们还需要添加一个偏置,来使得dp[3]里面的树,变为[4, 5, 6]组合的树。

3. Python实现

代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

# 返回修正偏差之后的树
def TreeNodeBias(n: TreeNode,bias: int) -> TreeNode:
    if n is None:
        return None
    else:
        nbias = TreeNode(n.val + bias)
        nbias.left = TreeNodeBias(n.left, bias)
        nbias.right = TreeNodeBias(n.right, bias)
    return nbias
# 动态规划  
class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        if(n == 0):
            return []
        """
        存放树的根节点
        dp[i]表示前i个整数所生成的二叉搜索树的根节点
        """
        dp = []  
        # 初始化dp列表
        for _ in range(n+1):
            dp.append([])
        dp[0].append(TreeNode(None))
        dp[1].append(TreeNode(1))
        """
        i: 表示前i个整数, i <= n
        j: 表示前i个整数的第j个数当做根节点
        """
        for i in range(2, n+1):
            for j in range(1, i+1):
                left_num = j-1    # dp[left_num]为左子树的组合数
                right_num = i-j   # dp[right_num]为右子树的组合数
                # 对左右子树的可能的情况进行组合
                for left in range(len(dp[left_num])):
                    for right in range(len(dp[right_num])):
                        temp = TreeNode(j)   # 根节点为j
                        if left_num == 0:    # 如果j为1,那么左子树肯定是None
                            temp.left = None
                        else:                # 否则,依次添加左子树
                            temp.left = dp[left_num][left]
                        if j != i:           # 如果j == i,那么右子树肯定为None,因为是右子树,所以不用考虑添加None
                            temp.right = TreeNodeBias(dp[right_num][right], i-right_num)
                        dp[i].append(temp)
        return dp[n]

运行结果为:
在这里插入图片描述

发布了182 篇原创文章 · 获赞 243 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_42580947/article/details/105422479