一. Unique Binary Search Trees
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
Difficulty:Medium
TIME:21MIN
解法(動態規劃)
其實這道題採用的就是典型的分治法,以根節點爲中心,將二叉查找樹分爲左右兩個子二叉查找樹,然後分別計算子二叉查找樹數的可能個數,再相乘(注意這裏是相乘)。
比如對於3個結點的二叉查找樹,可以分爲<0,2>,<1,1>,<2,0>三種結構,因此總的個數爲2+1+2=5。
知道了做法只會就很容易聯想到動態規劃,這樣就可以避免重複計算相同的值,解法如下:
int numTrees(int n) {
if(n == 0)
return 0;
vector<int> dp(n + 1, 0);
dp[1] = 1;
dp[0] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j]; //左子樹個數乘以右子樹個數
}
}
return dp[n];
}
代碼的時間複雜度爲
二. Unique Binary Search Trees II
Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1…n.
For example,
Given n = 3, your program should return all 5 unique BST’s shown below.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
Difficulty:Medium
TIME:TIMEOUT
解法
這道題和上面那道題幾乎是一樣的,不過這道題是是求具體的二叉查找樹,而不是求個數,因此就不能使用動態規劃了。
其實思路是有點類似的,也是採用分治法,先求左右兩邊子樹的所有二叉查找樹,然後再加上根節點。
vector<TreeNode*> dfs(int left, int right) {
vector<TreeNode*> v;
/*空節點*/
if(left > right) {
v.push_back(NULL);
return v;
}
/*單節點*/
if(left == right) {
v.push_back(new TreeNode(left));
return v;
}
for(int i = left; i <= right; i++) {
vector<TreeNode*> l = dfs(left, i - 1); //生成所有左子樹
vector<TreeNode*> r = dfs(i + 1, right); //生成所有右子樹
/*用根節點連接所有左子樹和右子樹*/
for(int j = 0; j < l.size(); j++) {
for(int k = 0; k < r.size(); k++) {
TreeNode *root = new TreeNode(i);
root->left = l[j];
root->right = r[k];
v.push_back(root);
}
}
}
return v;
}
vector<TreeNode*> generateTrees(int n) {
vector<TreeNode*> v;
if(n == 0)
return v;
return dfs(1, n);
}
不太清楚代碼的時間複雜度。