105. 从前序与中序遍历序列构造二叉树

问题描述

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

分析

逻辑上,从前序遍历中依次从前往后获取根结点,从中序里获取根结点的序号后可以获取左子树和右子树,递归构建树即可。

分治/递归

class Solution {
public:
    vector<int> preorder;
    vector<int> inorder;
    unordered_map<int, int> um;
    // 分治
    TreeNode* solve(int pre_l, int pre_r, int in_l, int in_r) {
        if (in_l > in_r || pre_l > pre_r) {
            return nullptr;
        }
        int root_index = um[preorder[pre_l]];
        TreeNode* root = new TreeNode();
        root->val = inorder[root_index];
        int n = root_index-in_l;
        root->left = solve(pre_l+1, pre_l+n+1, in_l, root_index-1);
        root->right = solve(pre_l+n+1, pre_r, root_index+1, in_r);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        this->preorder = preorder;
        this->inorder = inorder;
        for (int i = 0; i < inorder.size(); i++) {
            um[inorder[i]] = i; // 值为x的结点在中序遍历中是第i个
        }
        TreeNode* root;
        root = solve(0, preorder.size()-1, 0, inorder.size()-1);
        return root;
    }
};

拓展

事实上,solve的第二个参数pre_r可以更大,甚至可以去掉,因为每次递归只需找到该子树的前序遍历的第一个元素即可。

class Solution {
public:
    vector<int> preorder;
    vector<int> inorder;
    unordered_map<int, int> um;
    // 分治
    TreeNode* solve(int pre_l, int in_l, int in_r) {
        if (in_l > in_r) {
            return nullptr;
        }
        int root_index = um[preorder[pre_l]];
        TreeNode* root = new TreeNode();
        root->val = inorder[root_index];
        int n = root_index-in_l; // 左子树结点数量
        root->left = solve(pre_l+1, in_l, root_index-1);
        root->right = solve(pre_l+n+1, root_index+1, in_r);
        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        this->preorder = preorder;
        this->inorder = inorder;
        for (int i = 0; i < inorder.size(); i++) {
            um[inorder[i]] = i; // 值为x的结点在中序遍历中是第i个
        }
        TreeNode* root;
        root = solve(0, 0, inorder.size()-1);
        return root;
    }
};

该代码也能ac。

posted @   saulstavo  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示