問題:
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.
image.png
大意:
給出n,包含1~n這些節點可以形成多少個不同的BST(二叉查找樹)?
比如,
給出n = 3,有5個不同的BST:
image.png
思路:
二叉查找樹的性質是左子節點一定小于父節點,右子節點一定大于父節點。
我們思考一下可以發現,要形成不同的二叉樹,最基本的分類是1n各自都做一次根節點。在它們作為根節點時,又分別還有多少種不同的組合方式呢?由于這是一個二叉查找樹,那么根節點的左邊一定都是小于他的數,右邊一定都是大于它的數,所以1n就會被分成兩部分去放置,這時候由可以分別把左子節點、右子節點分別看成要安放一部分數字的根節點,又變成了一樣的規律。
所以假設以i為根節點,可能的組合情況為F(i,n),而G(n)為輸入n后的結果。則
F(i,n) = G(i-1)*G(n-i)
也就是左子節點以下的可能數量乘以右子節點以下的可能數量。
而因為1~n都可能作為根節點,所以最終的值是它們的和,也就是
G(n) = F(1,n) + F(2,n)?。 。疲ǎ睿睿?/p>
換算一下就是
G(n)?。健。牵ǎ埃?* G(n-1) + G(1) * G(n-2) + …… + G(n-1) *G(0)
其中我們可以直接看出?。牵ǎ埃。健。牵ǎ保。健。薄_@個作為初始值來遞歸計算就可以了,要知道G(n),我們必須把前面的數都計算出來。
代碼(Java):
public class Solution {
public int numTrees(int n) {
int[] res = new int[n+1];
res[0] = 1;
res[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
res[i] += res[j-1] * res[i-j];
}
}
return res[n];
}
}
合集:https://github.com/Cloudox/LeetCode-Record