889. Construct Binary Tree from Preorder and Postorder Traversal

406 篇文章 0 订阅
406 篇文章 0 订阅

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内的值和其索引进行映射
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值