一. 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];
}
代码的时间复杂度为 O(n2) 。
二. 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);
}
不太清楚代码的时间复杂度。