class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int 二叉树节点数量
* @param pre intvector 前序序列
* @param suf intvector 后序序列
* @return intvector
*/
int len=0;
void middleset(int prevleft,int prevright,vector<int>&pre,int sufleft,int sufright,vector<int>&suf,int ans[])
{
if(prevleft > prevright)return;
if(prevleft == prevright)
{
ans[len++]=pre[prevleft];
return;
}
int pos=-1;
for(int i=sufleft;i <= sufright; i++)
{
if(suf[i] == pre[prevleft+1])//在后序遍历中找到根结点的左子树的位置
//是找根节点的左子树,而不是找根节点
{
pos=i;
}
}
//递归 先序遍历的左子树和后序遍历的左子树
middleset(prevleft+1,pos-sufleft+prevleft+1,pre,sufleft,pos,suf,ans);
ans[len++]=pre[prevleft];
//递归 先序遍历的右子树和后序遍历的右子树
middleset(pos-sufleft+prevleft+2,prevright,pre,pos+1,sufright-1,suf,ans);
}
// prevleft+1是先序遍历的左子树的根节点,pos-sufleft+prevleft+1则是到达左子树的最右边
// sufleft仍然还是后序遍历的左子树的起始位置,pos则是后序遍历的左子树的最后一个位置,pos后面就是右子树第一个位置
//
/*逐条语句解析
//pos是先序遍历中根节点的左子树的位置,,同时也是后序遍历中左右子树的分界点的左子树的最后一点
//pos-sufleft+prevleft+2,是先序遍历右子树的左边界初始位置
prevright仍旧还是先序遍历整颗子树的最右边界
pos+1可以恰好到达后序遍历的右子树的第一个位置
sufright-1则是减去根节点位置(只看右子树)不考虑右子树的父节点
//递归右子树
*/
vector<int> solve(int n, vector<int>& pre, vector<int>& suf)
{
int ans[100010];
// write code here
vector<int>ansv;
middleset(0,n-1,pre,0,n-1,suf,ans);//
for(int i=0;i<len;i++)ansv.push_back(ans[i]);
return ansv;
}
};