个人记录-LeetCode 96. Unique Binary Search Trees

来源:互联网 发布:雪梨淘宝店名叫什么 编辑:程序博客网 时间:2024/06/10 15:39

问题:
Given n, how many structurally unique BST’s (binary search trees) that store values 1…n?

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

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

这个问题与LeetCode 95类似,
只不过此问题仅需要给出搜索树的数量。


代码示例:
1、该问题可以采取与LeetCode 95同样的解决方案,不过运行的结果超时。

public class Solution {    public int numTrees(int n) {        if (n < 1) {            return 0;        }        return innerHelper(1, n);    }    private int innerHelper(int start, int end) {        if (start >= end) {            return 1;        }        int count = 0;        //同样,以第i个数作为根节点        //计算出左、右树可能情况的数量        for (int i = start; i <= end; ++i) {            int left = innerHelper(start, i-1);            int right = innerHelper(i + 1, end);            //累计得到运算结果            count += left * right;        }        return count;    }}

2、DP

DP的思想的核心部分,与上面类似,只是做了进一步的优化。
假设我们用G(n)表示输入参数为n时的计算结果;
用F(i, n)表示第i (1 <= i <= n)个数为根节点,1~i-1组成左子树, i+1 ~ n组成右子树的结果;
那么显然:

//这实际上就是第一种解法的思想G(n) = F(1, n) + F(2, n) + ... + F(n, n)G(0)=1, G(1)=1

现在,我们进一步看看F(i, n)如何计算。

在第一种解法中,我们已经知道F(i, n)实际上就是:
1~i-1组成左子树组成左子树的数量,

i+1 ~ n组成右子树的数量
的积。

而实际上,1~i-1组成左子树的数量就是G(i-1); i+1 ~ n 组成右子树的数量就是G(n-i),
{组成子树的数量,与数据的范围有关,与起始、结束的值无关}

于是,易于看出:

F(i, n) = G(i-1) * G(n-i)   1 <= i <= n 

根据上述公式,就可以利用DP计算结果,代码如下:

public class Solution {    public int numTrees(int n) {        int [] G = new int[n+1];        G[0] = G[1] = 1;        //i表示数据的范围        for(int i=2; i<=n; ++i) {            //j表示根节点的位置            for(int j=1; j<=i; ++j) {                G[i] += G[j-1] * G[i-j];            }        }        return G[n];    }}
0 0
原创粉丝点击