通过前序中序,中序后序,前序后序来构造一二叉树

前序中序,以及中序后序可以确定唯一一颗二叉树,而前序后续是可以有多种情况,因为仅仅前序后续是无法确定根节点左右子树的问题;

首先解决通过前序和中序来构建一颗二叉树的问题;

前序=根节点+左子树+右子树

中序=左子树+根节点+右子树;

则我们可以通过查找根节点再中序中的位置来确定左子树再数组中的长度,进而确定右子树的长度,采用递归求解问题

我们采用哈希表map来建立对中序一对一的键值对应关系;

题目描述可参考力扣105题所描述如下

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

前序中序构建二叉树代码如下

class Solution {
public:
     unordered_map<int,int>pos;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
          int n=preorder.size();
          for(int i=0;i<n;i++){
              pos[inorder[i]]=i;
          }
          return dfs(preorder,inorder,0,n-1,0,n-1);
    }
    TreeNode*dfs(vector<int>&pre,vector<int>&in,int pl,int pr,int il,int ir){
        if(pl>pr||il>ir)return NULL;
        int k=pos[pre[pl]]-il;
        TreeNode*root=new TreeNode(pre[pl]);
        root->left=dfs(pre,in,pl+1,pl+k,il,il+k-1);
        root->right=dfs(pre,in,pl+k+1,pr,il+k+1,ir);
        return root;
    }
};

同理,中序后续构建二叉树的代码如下

class Solution {
public:
    unordered_map<int,int>pos;
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int n=inorder.size();
        for(int i=0;i<n;i++){
            pos[inorder[i]]=i;
        }
        return dfs(inorder,postorder,0,n-1,0,n-1);
    }
    TreeNode*dfs(vector<int>&in,vector<int>&po,int il,int ir,int pl,int pr){
        if(il>ir)return NULL;
        TreeNode*root=new TreeNode(po[pr]);
        int k=pos[po[pr]]-il;
        root->left=dfs(in,po,il,il+k-1,pl,pl+k-1);
        root->right=dfs(in,po,il+k+1,ir,pl+k,pr-1);
        return root;
    }
};

前序后序建立二叉树如下

class Solution {
public:
    unordered_map<int,int>mymap;
    TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
        if(postorder.size()==0)return NULL;
        int size=postorder.size();
        for(int i=0;i<size;i++){
            mymap[postorder[i]]=i;
        }
        return BuildTree(preorder,postorder,0,size-1,0,size-1);

    }
private:
    TreeNode*BuildTree(vector<int>pre,vector<int>po,int l,int r,int ll,int rr){
        if(l>r||ll>rr)return NULL;
        if(l==r||ll==rr){
            TreeNode*yezi=new TreeNode(pre[l]);
            return yezi;
        }
        int k=mymap[pre[l+1]]-ll;
        TreeNode*root=new TreeNode(pre[l]);
        root->left=BuildTree(pre,po,l+1,l+1+k,ll,ll+k);
        root->right=BuildTree(pre,po,l+2+k,r,ll+k+1,r-1);
        return root;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值