您的位置:首页 > 产品设计 > UI/UE

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

2017-04-11 20:15 459 查看
问题:

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
;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: