【算法分析与设计】【第十周】96. Unique Binary Search Trees

来源:互联网 发布:json在线解析java对象 编辑:程序博客网 时间:2024/06/15 22:20

题目来源:96:https://leetcode.com/problems/unique-binary-search-trees/description/

动态规划基础训练2。

  • Unique Binary Search Trees
    • 题目大意
    • 思路
      • 卡特兰数
      • 特殊情况分析
      • 状态转移式
    • 解题代码
    • 复杂度

96. Unique Binary Search Trees

题目大意

给定一个数n,求出节点数为n的二叉搜索树的个数。

For example,
Given n = 3, there are a total of 5 unique BST’s.
ex


思路

卡特兰数

啥是卡特兰数?在做这题之前我也是懵懵哒。

卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 : 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …

卡特兰数满足以下性质:
令h(0)=1,h(1)=1,catalan数满足递推式:
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + … + h(n-1)h(0) (n>=2)
也就是说,如果能把公式化成上面这种形式的数,就是卡特兰数。

当然,上面这样的递推公式太繁琐了,于是数学家们又求出了可以快速计算的通项公式:
h(n)=c(2n,n)-c(2n,n+1)(n=0,1,2,…)。
这个公式还可以更简单得化为h(n)=C(2n,n)/(n+1)。

上面的解释比较官方, wuyuegb2312介绍的很好,可以了解一下。

特殊情况分析

  • 如果集合为空(n=0),只有一种BST,即空树,
    UniqueTrees[0] =1

  • 如果集合仅有一个元素(n=1),只有一种BST,即为单个节点
    UniqueTrees[1] = 1

  • 集合有三个元素(n=3),可以发现BST的取值方式如下:
    UniqueTrees[2] = UniqueTrees[0] * UniqueTrees[1] (1为根的情况)+
    UniqueTrees[1] * UniqueTrees[0] (2为根的情况)

  • 再看一集合有三个元素(n=3),可以发现BST的取值方式如下:
    UniqueTrees[3] = UniqueTrees[0]*UniqueTrees[2] (1为根的情况)+
    UniqueTrees[1]*UniqueTrees[1] (2为根的情况)+
    UniqueTrees[2]*UniqueTrees[0] (3为根的情况)

所以,由此观察,可以得出UniqueTrees的递推公式为

UniqueTrees[i]=UniqueTrees[0...k][i1k],k0<=k<=(i1)

状态转移式

dp[i]+=dp[j]dp[ij1];

据说,这正是卡特兰数的一种定义方式,是一个典型的动态规划的定义方式(根据其实条件和递推式求解结果)。所以思路也很明确了,维护量UniqueTrees[i]表示含有i个结点的二叉查找树的数量。根据上述递推式依次求出1到n的的结果即可。

当然,上述总结非常玄幻。不查资料几乎很难自己总结出来。
秋雨解决这个问题很有一套,可以看看。


解题代码

一旦状态转移式出来,问题就很简单了。
代码简明清晰,用二重循环实现。

class Solution {public:    int numTrees(int n) {        int dp[n+1] = {0};        dp[0] = dp[1] = 1;        for (int i = 2; i <= n; i++) {            for (int j = 0; j < i; j++) {                dp[i] += dp[j] * dp[i-j-1];            }        }        return dp[n];    }};

复杂度

动态规划时间复杂度:O(n^2);空间复杂度: O(n)。

用卡特兰数的通项公式来求解,时间复杂度就可以降低到O(n)。


原创粉丝点击