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