889. Construct Binary Tree from Preorder and Postorder Traversal

1,题目要求
Return any binary tree that matches the given preorder and postorder traversals.

Values in the traversals pre and post are distinct positive integers.
这里写图片描述
根据先序遍历和后序遍历的结果,构造一颗满足条件的树。

2,题目思路
对于这道题,首先需要思考的是,如果仅仅是在纸面上去构建这样的树,应该怎样去创建?
这里就需要对先序遍历和后序遍历的各自特点进行分析了。
对于先序遍历而言,最先遍历的一定是根节点,然后分别是左右子树,因此,遍历的结果如下图所示:
[root][…left…][…right…]
而对于后序遍历,则类似的,最后去遍历的才是根节点,因此:
[…left…][…right…][root]
因此,我们要找到的就是这样的left和right部分,即找到他们分别的开始位置以及结束位置。
首先,我们对后序遍历的结果进行映射(value -> index),这样,我们就可以根据在前序遍历中找到的值,找到后序遍历里的对应的值所在后序遍历结果中的位置。
就像题目中所示,
先序遍历:[1][2,4,5][3,6,7]
后序遍历:[4,5,2][6,7,3][1]
对于先序遍历中的2,后续中它正好就是left的最后一个元素,因此,这个index - postStart就是left的长度。
同样的,也可以很轻松的找到right的长度、在pre和post里的开始位置和结束位置。

3,程序源码

class Solution {
public:
    TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post) {
        int len = pre.size();
        for(int i = 0;i<len;i++)
            m[post[i]] = i;     //对后序遍历进行value -> index的映射
        return coHelper(pre, post, 0, len-1, 0, len-1);

    }

    TreeNode* coHelper(vector<int>& pre, vector<int>& post, int preStart, int preEnd, int postStart, int postEnd)
    {
        if(preStart>preEnd) return nullptr;

        TreeNode* root = new TreeNode(pre[preStart]);   //作为左右子树的划分位置
        if(preStart == preEnd)  return root;

        int idx = m[pre[preStart+1]];   //先序遍历中,左子树的第一个节点在后序遍历的列表中的位置
        int offset = idx - postStart;   //表示左子树的长度(节点的数量),设定一个偏移量来进行表示

        root->left = coHelper(pre, post, preStart+1, preStart+1+offset, postStart, idx);
        root->right = coHelper(pre, post, preStart+1+offset+1, preEnd, idx+1, postEnd);

        return root;

    }
private:
    unordered_map<int, int> m;//对于post内的值和其索引进行映射
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值