(2015/11/15)
LeetCode-95 Unique Binary Search Trees II:(Medium)(do more time)
题目大意:给定n,生成所有中序遍历为1...n的二叉树。
解题思路:
1)定义函数:void makeTree(int rootval, vector<int> allnodes, vector<TreeNode *> &ans)
rootval:为根结点的值。
allnodes:为此树中所有结点的值的集合。
ans:存放以rootval为根结点的值的所有可能的二叉树。
makeTree函数的执行过程:
1)以rootval作为根结点的值,比rootval大的值放在右子树值的集合,比rootval小的值放在左子树值的集合。
2)递归调用makeTree,生成左右子树的集合。
3)根据返回的左右子树集合的大小,生成以rootval为根结点值的树。
class Solution {
public:
vector<TreeNode*> generateTrees(int n){
vector<int> allnodes;
for(int i = 1; i <= n; i++) allnodes.push_back(i);
vector<TreeNode *> ans;
if(n == 0){
TreeNode *tmp = NULL;
ans.push_back(tmp);
}
for(vector<int>::size_type i = 0; i < allnodes.size(); i++)
makeTree(allnodes[i], allnodes, ans);
return ans;
}
void makeTree(int rootval, vector<int> allnodes, vector<TreeNode *> &ans){
vector<int> leftnodes, rightnodes;
for (vector<int>::size_type i = 0; i < allnodes.size(); i++){
if (allnodes[i] > rootval) rightnodes.push_back(allnodes[i]);
else if (allnodes[i] < rootval) leftnodes.push_back(allnodes[i]);
}
vector<TreeNode *> leftsubtree, rightsubtree;
for(vector<int>::size_type i = 0; i < leftnodes.size(); i++)
makeTree(leftnodes[i], leftnodes, leftsubtree);
for(vector<int>::size_type i = 0; i < rightnodes.size(); i++)
makeTree(rightnodes[i], rightnodes, rightsubtree);
TreeNode *tmp;
if(leftsubtree.size() == 0 && rightsubtree.size() == 0){
tmp = new TreeNode(rootval);
ans.push_back(tmp);
return;
}
if(leftsubtree.size() != 0 && rightsubtree.size() == 0){
for(vector<TreeNode *>::size_type i = 0; i < leftsubtree.size(); i++){
tmp = new TreeNode(rootval);
tmp->right = NULL;
tmp->left = leftsubtree[i];
ans.push_back(tmp);
}
}
if(rightsubtree.size() != 0 && leftsubtree.size() == 0){
for(vector<TreeNode *>::size_type i = 0; i < rightsubtree.size(); i++){
tmp = new TreeNode(rootval);
tmp->right = rightsubtree[i];
tmp->left = NULL;
ans.push_back(tmp);
}
}
if(rightsubtree.size() != 0 && leftsubtree.size() != 0)
{
for(vector<TreeNode *>::size_type i = 0; i < leftsubtree.size(); i++){
for(vector<TreeNode *>::size_type j = 0; j < rightsubtree.size(); j++){
tmp = new TreeNode(rootval);
tmp->right = rightsubtree[j];
tmp->left = leftsubtree[i];
ans.push_back(tmp);
}
}
}
return;
}
};
解题体验:
首先看到这种题不要觉得难就不去思考,要把能想到的所有可能解法,解题思路写下来。
思路有了之后就要编程实现。这并不容易。
正确的算法及实现,其结构(框架)一定是清晰的。要在纸上多验证,算法的框架清晰了之后编程实现就容易了。
(比如此题:一定要想清楚什么时候new一个结点,这个结点怎么和父结点连接(如何把解传递给调用函数),怎么才能不漏掉解)