1. Problem Description
Given inorder and postorder traversal of a tree, construct the binary tree.
2. My solution
类似的题目还有105,是根据中序和前序重构二叉树。根据前序和后序是无法重构二叉树的,因为重构二叉树需要中序遍历顺序提供划分左右子树的方法。
Findroot函数主要是就是在中序遍历中找到src出现的位置。
Judge函数用来判断有没有越界。
Build函数的主要思想:
提供中序后序遍历顺序,以及当前查找的范围(中序查找范围lin~rin,后序查找范围lpost~rpost,这两个范围的长度应当相同)
1.越界返回空指针
2.当前根节点数值为后序遍历最后一个数。
3.找到根节点在中序遍历中的位置index。
4.新的中序遍历范围,左子树为lin~index-1,右子树为index+1~rin。
5.新的后序遍历范围,长度应该和中序相同.
根据4计算出中序遍历中左子树范围是index-lin,右子树范围是rin-index。
而后序遍历左端点应该是lpost,右端点应当是rpost-1.
所以左子树范围在[lpost,lpost+cnt-1],右子树范围在[rpost-1-cnt+1,rpost-1]。
接口函数buildTree:开始建树时,中序遍历和后序遍历的查找范围都是0到len-1
class Solution
{
private:
int len;
public:
int findroot(vector<int>& inorder,int ll,int rr,int src)
{
for(int i=ll; i<=rr; i++)
if(inorder[i]==src)
return i;
return -1;
}
bool judge(int ll,int rr)
{
if(ll<=rr&&ll>=0&&rr>=0&&ll<len&&rr<len)
return true;
else
return false;
}
TreeNode* build(vector<int>& postorder, vector<int>& inorder,int lpost,int rpost,int lin,int rin)
{
if(!(judge(lpost,rpost)&&judge(lin,rin)))
return NULL;
TreeNode*root=new TreeNode(0);
root->val=postorder[rpost];
int index=findroot(inorder,lin,rin,root->val);
int cntl=index-lin;
int cntr=rin-index;
root->left=build(postorder,inorder,lpost,lpost+cntl-1,lin,index-1);
root->right=build(postorder,inorder,rpost-1-cntr+1,rpost-1,index+1,rin);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
len=postorder.size();
TreeNode*root=build(postorder,inorder,0,len-1,0,len-1);
return root;
}
};