原题如下:
Given preorder and inorder traversal of a tree, construct the binary tree.
这道题的思路还是比较明确的,首先从前序遍历中取根节点,然后根据根节点将中序遍历分为左子树和右子树,然后再根据中序遍历的左子树和右子树分别确定前序遍历的左子树和右子树,然后依次递归。
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
if(inorder.size() == 0 || postorder.size() == 0 || inorder.size() != postorder.size())
return NULL;
int n = inorder.size();
return built(inorder,postorder,0,n - 1,0, n - 1);
}
TreeNode *built(vector<int>&inorder,vector<int>&postorder,int inStart,int inEnd,int postStart, int postEnd){
if(inStart > inEnd || postStart > postEnd)
return NULL;
TreeNode *root = new TreeNode(postorder[postEnd]);
if(inStart == inEnd)
return root;
int leftLen = 0;//记录左子树的长度
int i = inStart;//i标记中序inorder中根的下标
for(;i < inEnd; i++){
if(inorder[i] == root->val)
break;
leftLen++;
}
root->left = built(inorder,postorder,inStart,i - 1,postStart,postStart + leftLen - 1);
root->right = built(inorder,postorder,i + 1,inEnd,postStart + leftLen, postEnd - 1);
return root;
}
从这道题中吸取的深刻教训是:传值和传引用的区别,在将占内存比较大的对象作为参数传递时,最好选择传引用,这样可以减少内存消耗,就因为少了&符号,程序提交一直出现
Memory Limit Exceeded错误,害的我郁闷了半天。。。
从中序和后序建立二叉树的思路和这道题的思路一样,所以就不多说了,直接上代码了:
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
if(inorder.size() == 0 || postorder.size() == 0 || inorder.size() != postorder.size())
return NULL;
int n = inorder.size();
return built(inorder,postorder,0,n - 1,0, n - 1);
}
TreeNode *built(vector<int>&inorder,vector<int>&postorder,int inStart,int inEnd,int postStart, int postEnd){
if(inStart > inEnd || postStart > postEnd)
return NULL;
TreeNode *root = new TreeNode(postorder[postEnd]);
if(inStart == inEnd)
return root;
int leftLen = 0;//记录左子树的长度
int i = inStart;//i标记中序inorder中根的下标
for(;i < inEnd; i++){
if(inorder[i] == root->val)
break;
leftLen++;
}
root->left = built(inorder,postorder,inStart,i - 1,postStart,postStart + leftLen - 1);
root->right = built(inorder,postorder,i + 1,inEnd,postStart + leftLen, postEnd - 1);
return root;
}
};
基础不牢固导致出现各种细小差错,而这些细小差错就可能导致致命错误,教训深刻!