leetcode 106. 从中序与后序遍历序列构造二叉树

题目描述

题目链接:leetcode 106. 从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

返回如下的二叉树:

        3
       / \
      9  20
         /  \
        15   7

由中序与后序遍历序列构造二叉树

给定如下二叉树:
在这里插入图片描述中序遍历(左根右):ACBDFHEMG
后序遍历(左右根):ABDCHMGEF

由中序与后序遍历序列构造二叉树的步骤:
1.在后序中找到最后一个字母F,F必为二叉树的根。在中序中找到F:ACBDHEMG。中序遍历中F左边的字母ACBD必在F的左子树上,中序遍历中F右边的字母HEMG必在F的左子树上。如下图所示:
在这里插入图片描述
F将中序划分为左边4个字母和右边4个字母,故在后序中把F删掉得到序列ABDCHMGE,再把此序列分为前4个(ABDC)和后4个(HMGE)。如下图所示:
在这里插入图片描述2.可以看到,问题又变成了两个子问题:
(1)由中序遍历ACBD和后序遍历ABDC求左子树。
(2)由中序遍历HEMG和后序遍历HMGE求右子树。
故只需获得解决整体问题的方法,再递归求解子问题即可—分治的思想。

C++代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public: 
     /*
     dfs参数说明:
     l:定位前序的起始位置
     r:定位前序的终止位置
     last:定位后序的末尾
     */
    TreeNode* dfs(vector<int>& inorder, vector<int>& postorder,int l,int r,int last){
        TreeNode *root=NULL;
        for(int i=l;i<=r;i++)
        {
            if(inorder[i]==postorder[last]) //找到后序的最后一个节点
            {
                root=new TreeNode();
                root->val=inorder[i]; //令后序的最后一个节点为当前子树的根
        //递归构造左右子树,其中对左右子树“last”的更新可以对照中后序确定
                root->left=dfs(inorder,postorder,l,i-1,last-(r-i+1));
                root->right=dfs(inorder,postorder,i+1,r,last-1);
                 break;
            }   
        }
        return root;
    }   

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int l=0,r=inorder.size()-1,last=postorder.size()-1;
        return dfs(inorder,postorder,l,r,last);
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值