Leetcode 95 Unique Binary Search Trees II

Posted yuyinzi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode 95 Unique Binary Search Trees II相关的知识,希望对你有一定的参考价值。

题目介绍

给定正整数n,利用1n构造所有可能的二叉树,并返回。

Example:

Input: 3
Output:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST‘s shown below:

   1         3     3      2      1
           /     /      /            3     2     1      1   3      2
    /     /                           2     1         2                 3

Solution

一开始想用回溯去做,但是发现root所做的更改将会影响到前面的结果。后面发现应该使用动态规划(为啥哪都可以用上动态规划= =):

取每一个节点i,那么它的左子树由[1,i-1]组成,右子树由[i+1, n]组成。左右子树的构成方法又可以分解为更小的问题。以此类推。

class Solution(object):
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """ 
        if n == 0:
            return []
        def helpfunc(start, end):
            temp = []
            # 如果右边界比左边界小,不存在子树,返回[None]用以遍历
            if start > end:
                return [None]
            # 如果左右边界相等,返回节点自身,例如求2,3的组成,当节点为2时,其右子树应当为[3]
            if start == end:
                temp.append(TreeNode(start))
                return temp
            for i in range(start, end + 1):
                ltrees = helpfunc(start, i - 1)
                rtrees = helpfunc(i + 1, end)

                for ltree in ltrees:
                    for rtree in rtrees:
                        # 每次都能生成不同的根节点
                        node = TreeNode(i)
                        node.left = ltree
                        node.right = rtree
                        temp.append(node)
            return temp

        ans = helpfunc(1, n)
        return ans

延伸

Leetcode 96 Unique Binary Search Trees

这道题目只要求求出总共有多少种可能。根据上面的思路,可以得出:

dp[start][end] = dp[start][k-1] * dp[k+1][end], for k in [start, end]

很自然的会想到使用二维的dp数组,但是需要注意的是:

  1. k==start或者k==end时,会导致越界,此时应当单独赋值。例如:

    nums=1,2时,此时dp[1][2]= dp[1][0] * dp[2,2] + dp[1][1]*dp[3][2],因为dp[1][2]dp[3][2]可以代表空节点,所以应当有意义。

  2. nums=1,2,3时,求dp[1][3]需要依赖dp[2][3],因此需要从左至右,从下至上进行计算。

class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n < 1:
            return 1
        dp = [[0 for i in range(n + 1)] for j in range(n + 1)]

        for i in range(n, 0, -1):
            for j in range(1, n + 1):
                if i == j:
                    dp[i][j] = 1
                else:
                    for k in range(i, j+1):
                        if k == i:
                            dp[i][j] += dp[k+1][j]
                        elif k == j:
                            dp[i][j] += dp[i][k-1]
                        else:
                            dp[i][j] += dp[i][k-1] * dp[k + 1][j]

        return dp[1][n]

然而,可以使用一维数组解决,因为只要考虑个数,不用考虑特定的下标,即dp[2][3]dp[1][2]的值其实没有本质区别。

假设G[n]=F(1,n)+F(2,n)+...+F(n,n)F(i,n)代表以i为根有多少种树。

同时,F(i,n)=G(i-1)*G(n-i),即以i为根,左边树的个数为以i-1为根的树种类,右边树的个数为[i+1, n],等价于G(n-i)

特别地,当n==0n==1时,只有1种树,这个作为初始条件。

G[2]为例,G[2]=F(1,2)+F(2,2)=G[0]*G[1]+G[1]*G[0]

class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        G = [0 for i in range(n+1)]
        
        G[0] = G[1] = 1
        
        for i in range(2, n+1):
            for j in range(1, i+1):
                G[i] += G[i-j] * G[j-1]
        
        return G[n]

以上是关于Leetcode 95 Unique Binary Search Trees II的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 95. Unique Binary Search Trees II

LeetCode 95. Unique Binary Search Trees II

[leetcode-95-Unique Binary Search Trees II]

leetcode95 Unique Binary Search Trees II

leetcode [95]Unique Binary Search Trees II

[LeetCode] 95. Unique Binary Search Trees II