边工作边刷题:70天一遍leetcode: day 20

Unique Binary Search Trees I/II

要点: structurally unique的内涵是什么?输出所有组合时的编号如何处理

  • 对于II,因为需要输出所有,不同区间的输出是不同的。所以要iterate所有区间,在每个区间内,需要用catalan number的iteration方式loop所有点作为root。无论是dp或者memoization,思路类似。
  • 注意这题和Burst Balloons类似,不是单向dp,需要用长度作为outer loop
  • 这题还有个tricky的地方:因为左右子树可能为null,在loop root和左右子树集合的时候,如何把null也包含到左右子树集合里?如果以长度作为dp的一维,可以把0作为一项,这里左右子树对应的是只有一个元素null的集合。
    • 当然也可以对左右子树为null的情况特殊处理,这里一个小技巧是判断是否k和左右边界相同,相同则建一个只有null的集合[null],这样和iterate左右子树集合的code一致了。

I: dp

  • 一类dp的代表,dp每个元素表示前i个结点的bst个数。对i个结点中的每一个点,作为root累积个数。
  • 因为有null可能为左/右子树,所以dp的长度为n+1
  • 左右子树结点个数的计算:i即表示结点个数,也表示以1初始的子树index,所以可以通过index计算其左右子树个数(这个是这题最不容易记住的地方,因为通常都是index比个数小1)
class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [0]*(n+1)
        dp[0]=1
        dp[1]=1
        for i in range(2, n+1):
            for k in range(1, i+1):
                dp[i]+=dp[k-1]*dp[i-k]
                
        return dp[n]

posted @ 2016-04-29 09:58  absolute100  阅读(114)  评论(0编辑  收藏  举报