中序序列

思路

易知:

前序遍历顺序为:根、左子树、右子树;
中序遍历顺序为:左子树、根、右子树;
后序遍历顺序为:左子树、右子树、根;

由前序遍历可知,整棵树的根节点是

对于样例:

3 2 1 4 5
1 5 4 2 3

结合前序、后序遍历可得整棵树的结构:

图片说明

得到规律:

在先序遍历序列中,根节点之后是左儿子结点;在后序遍历序列中,根节点之前是右儿子结点。

枚举先序遍历中的节点,结合其在后序遍历中的位置,判断其子树所包含节点范围,递归求解即可。

Code

class Solution{
private:
    vector<int> ans;
    vector<int> pre, suf;
    struct node {
        int val;
        node *lson = NULL, *rson = NULL;
    };

public:
    node *build(int l1, int r1, int l2, int r2) {
        if (l1 > r1) return nullptr;
        node *cur = new node();
        cur->val = pre[l1];
        if (l1 == r1) return cur;
        int pos;
        for (int i = l2; i <= r2; ++i) {
            if (pre[l1 + 1] == suf[i]) {
                pos = i;
                break;
            }
        }
        cur->lson = build(l1 + 1, pos - l2 + l1 + 1, l2, pos);
        cur->rson = build(pos - l2 + l1 + 2, r1, pos + 1, r2 - 1);
        return cur;
    }

    void dfs(node *cur) {
        if (cur == NULL) return ;
        dfs(cur->lson);
        ans.push_back(cur->val);
        dfs(cur->rson);
    }

    vector<int> solve(int n, vector<int> npre, vector<int> nsuf) {
        pre.push_back(0);
        suf.push_back(0);
        for (int i = 0; i < n; ++i) {
            pre.push_back(npre[i]);
            suf.push_back(nsuf[i]);
        }
        node *root = build(1, n, 1, n);
        dfs(root);
        return ans;
    }
};

优化

在上述思路的基础上,去掉建树过程,可直接在数组上递归求解。

Code

  class Solution {
public:
    /**
     * 返回所求中序序列
     * @param n int整型 二叉树节点数量
     * @param pre int整型vector 前序序列
     * @param suf int整型vector 后序序列
     * @return int整型vector
     */
    vector<int>in;
    void build(int pl, int pr, int sl, int sr, vector<int>& pre, vector<int>& post, int l=0,int r=0)
    {
        if (pl > pr || sl > sr)
            return;
        int i;
        for (i = sr - 1; i >= sl && post[i] != pre[pl + 1]; i--);
        int left = i - sl + 1;
        in[l + left] = pre[pl];
        build(pl + 1, pl + left, sl, i, pre, post,l);
        build(pl + left + 1, pr, i + 1, sr - 1, pre,post, l+left+1);
    }
    vector<int> solve(int n, vector<int>& pre, vector<int>& suf) {
        // write code here
        in = vector<int>(n);
        build(0, n - 1, 0, n - 1, pre, suf);
        return in;
    }
};
全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务