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;
}
};