18. 重建二叉树

输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。

注意:

二叉树中每个节点的值都互不相同;
输入的前序遍历和中序遍历一定合法;
样例

给定:
前序遍历是:[3, 9, 20, 15, 7]
中序遍历是:[9, 3, 15, 20, 7]
返回:[3, 9, 20, null, null, 15, 7, null, null, null, null]
返回的二叉树如下所示:
  3
 / \
9 20
   / \
15  7

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorder,inorder;//因为想在别的方法中使用buildTree的参数,所以把它定义成全局的
    map<int,int> m;//因为在中序遍历中查找某个值的下标需要O(n)的复杂度,可以使用hash降为O(1)
    TreeNode* buildTree(vector<int>& _preorder, vector<int>& _inorder) {
        preorder = _preorder;//将参数赋值为全局变量
        inorder = _inorder;
        for(int i=0;i< _inorder.size();i++)
            m[ _inorder[i]]=i;//将中序遍历的值和下标映射到map中
        return dfs(0, _preorder.size()-1,0, _inorder.size()-1);//重建二叉树
    }
    //pl、pr分别代表前序遍历的起始下标和结束下标
    //il、ir分别代表中序遍历的起始下标和结束下标
    TreeNode* dfs(int pl,int pr,int il,int ir){
        //因为该方法要使用中序遍历的起止下标算左右子树的结点个数,所以该方法需要传入中序遍历的起止下标
        if(pl>pr)//前序遍历该区间已无结点
            return NULL;
        //创建根结点
        auto root = new TreeNode(preorder[pl]);//注意点:记得要new
        int k=m[root->val];//查找中序遍历中根所在的下标
        //构建左子树,前序遍历的根是preorder[pl],所以其左子树的起始下标是pl+1,
        //其左子树共有k-il个结点(中序遍历中根左边都是左子树的结点),前序遍历的起始下标为pl+1
        //即在pl+1的基础上偏移k-il-1个位置为结束下标(该区间共有k-il个结点),所以pl+1+k-il-1=pl+k-il
        //因为中序遍历中根左边都是左子树的结点,所以起止下标分别为il、k-1
        root->left = dfs(pl+1,pl+k-il,il,k-1);
        //前序遍历中右子树的起始下标为左子树的结束下标+1,
        //中序遍历中根右边都是右子树的结点
        root->right = dfs(pl+k-il+1,pr,k+1,ir);
        return root;//返回以root为根的子树
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值