题目描述
思路
后序历遍,最后一个元素就是根节点的元素,于是就可以找到这个根节点在中序历遍中的位置,那么左子树的中序历遍和右子树的中序历遍就可以知道。由此可以知道左子树和右子树的节点数量,进而可以在后序历遍中确定左子树的后序历遍和右子树的后序历遍。之后,通过递归的思想,生成整棵树。
注意:
- 在递归调用程序中最后使用四个变量来指示,分别是(1)中序历遍的左端点,(2)中序历遍的右端点,(3)后序历遍的左端点,(4)后序历遍的右端点。相反如果只用3个变量来确定,那么思维过程很加大,很容易出错,程序也会变得难以理解。
解答
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/*
以下代码中变量名的意义:
1.in_start 代表每一段中序历遍的左端点
2.in_end 代表每一段中序历遍的右端点
3.post_start 代表每一段后序历遍的左端点
4.post_end 代表每一段后序历遍的右端点
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return fun(inorder,postorder,0, inorder.size(), 0,postorder.size()-1);
}
TreeNode* fun(vector<int>& inorder, vector<int>& postorder,int in_start, int in_end, int post_start, int post_end)
{
if(post_start==post_end) return new TreeNode(postorder[post_end]);
if(post_start > post_end) return NULL;
int root_value=postorder[post_end];
TreeNode* root=new TreeNode(root_value);
int i=0;
for(;i<in_end;++i)
{
if(inorder[i]==root_value)
break;
}
root->left=fun(inorder,postorder,in_start, i-1, post_start, post_start+ i-in_start-1);
root->right=fun(inorder,postorder,i+1, in_end, post_start+i-in_start, post_end-1);
return root;
}
};