题目如下:
Given 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.
我的代码:
Given 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 3confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.
分析如下:
和上一道题目是相关问题,显然也适合用递归来解决。
当前的递归中,假设root为i。那么显然左子树是由[1,i-1]构成的所有可能的组合,显然右子树是由[i+1,n]构成的所有可能的组合(可以统一记录为,用[start, end]去构建树)。在有了左子树,root,右子树的情况下,根据乘法原理很容易计算得出在当前情况下的所有的树。记录root到一个vector中就可以完整地记录所有结果。返回结果即可。
那么,怎么计算左子树或者右子树的所有可能,这是个和上面类似的问题。
临界条件是,
当[start,end]中star==end时,说明只有一个节点。于是返回这个节点。
当[start,end]中star<end时,返回NULL。
我的代码:
//112ms
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
return generateTrees1(1,n);
}
vector<TreeNode*> generateTrees1(int start, int end){
if(start>end){
vector<TreeNode*> res_vec;
res_vec.push_back(NULL);
return res_vec;
}
else if(start==end){
vector<TreeNode*> res_vec;
TreeNode* res_node=new TreeNode(start);
res_vec.push_back(res_node);
return res_vec;
}
vector<TreeNode*> res_vec;
for(int i=start;i<=end;i++){
vector<TreeNode*> l_vec=generateTrees1(start, i-1);
vector<TreeNode*> r_vec=generateTrees1(i+1,end);
for(int k=0;k<l_vec.size();k++){
for(int j=0;j<r_vec.size();j++){
TreeNode* root=new TreeNode(i);
root->left=l_vec[k];
root->right=r_vec[j];
res_vec.push_back(root);
}
}
}
return res_vec;
}
};
update: 2014-12-19
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//34ms
class Solution {
public:
vector<TreeNode*> generateTreesHelper(int start, int end ) {
if (start > end) return vector<TreeNode*> {NULL};
vector<TreeNode*> final;
for (int i = start; i <= end; ++i) {
vector<TreeNode*> left = generateTreesHelper(start, i - 1);
vector<TreeNode*> right = generateTreesHelper(i + 1, end);
for (int j = 0; j < left.size(); ++j) {
for (int k = 0; k < right.size(); ++k) {
TreeNode* root = new TreeNode(i);
root->left = left[j];
root->right = right[k];
final.push_back(root);
}
}
}
return final;
}
vector<TreeNode *> generateTrees(int n) {
return generateTreesHelper(1, n);
}
};
update:
2015-03-23
其实没有上面那个版本写得简单了,上面的版本分了2个情况,下面的版本分了3个情况,虽然都是正确的。
不过,下面的版本用了一下vec.assgin(),以前很少用到这个函数。
// 25ms
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
vector<TreeNode *> generateTrees_(int start, int end) {
vector<TreeNode*> vec;
if (start > end) {
vec.assign(1, NULL); //Assigns new contents by replacing its current contents.
} else if (start == end) {
TreeNode* treenode = new TreeNode(start);
vec.assign(1, treenode);
} else {
for (int i = start; i <= end; ++i) {
vector<TreeNode*> left_vec = generateTrees_(start, i -1);
vector<TreeNode*> right_vec = generateTrees_(i + 1, end);
for (int j = 0; j < left_vec.size(); ++j) {
for (int k = 0; k < right_vec.size(); ++k) {
TreeNode* treenode = new TreeNode(i);
treenode->left = left_vec[j];
treenode->right = right_vec[k];
vec.push_back(treenode);
}
}
}
}
return vec;
}
public:
vector<TreeNode *> generateTrees(int n) {
return generateTrees_(1, n);
}
};
小结如下:
(1)递归每次都返回一堆节点,而不是一个节点。当递归的返回结果为多个时,为了方便处理,可以把这些结果打包放入一个vector中。
(2) 依然是典型的DFS题目。