【leetcode面试经典150题】73. 从中序与后序遍历序列构造二叉树(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主,题解使用C++语言。(若有使用其他语言的同学也可了解题解思路,本质上语法内容一致)

【题目描述】

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

【示例一】

复制代码
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

【示例二】

复制代码
输入:inorder = [-1], postorder = [-1]
输出:[-1]

【提示及数据范围】

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

【代码】

cpp 复制代码
// 方法一:递归

class Solution {
    int post_idx;
    unordered_map<int, int> idx_map;
public:
    TreeNode* helper(int in_left, int in_right, vector<int>& inorder, vector<int>& postorder){
        // 如果这里没有节点构造二叉树了,就结束
        if (in_left > in_right) {
            return nullptr;
        }

        // 选择 post_idx 位置的元素作为当前子树根节点
        int root_val = postorder[post_idx];
        TreeNode* root = new TreeNode(root_val);

        // 根据 root 所在位置分成左右两棵子树
        int index = idx_map[root_val];

        // 下标减一
        post_idx--;
        // 构造右子树
        root->right = helper(index + 1, in_right, inorder, postorder);
        // 构造左子树
        root->left = helper(in_left, index - 1, inorder, postorder);
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        // 从后序遍历的最后一个元素开始
        post_idx = (int)postorder.size() - 1;

        // 建立(元素,下标)键值对的哈希表
        int idx = 0;
        for (auto& val : inorder) {
            idx_map[val] = idx++;
        }
        return helper(0, (int)inorder.size() - 1, inorder, postorder);
    }
};

// 方法二:迭代

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (postorder.size() == 0) {
            return nullptr;
        }
        auto root = new TreeNode(postorder[postorder.size() - 1]);
        auto s = stack<TreeNode*>();
        s.push(root);
        int inorderIndex = inorder.size() - 1;
        for (int i = int(postorder.size()) - 2; i >= 0; i--) {
            int postorderVal = postorder[i];
            auto node = s.top();
            if (node->val != inorder[inorderIndex]) {
                node->right = new TreeNode(postorderVal);
                s.push(node->right);
            } else {
                while (!s.empty() && s.top()->val == inorder[inorderIndex]) {
                    node = s.top();
                    s.pop();
                    inorderIndex--;
                }
                node->left = new TreeNode(postorderVal);
                s.push(node->left);
            }
        }
        return root;
    }
};
相关推荐
qq_452396233 小时前
第四篇:《索引原理与实战:B-tree、Hash、GIN、GiST、BRIN》
算法·哈希算法·gin
西索斯coding3 小时前
Qwen3-Max 与 Qwen-Plus:60 个真实修复任务评测方案
大数据·网络·算法·ai
加洛斯3 小时前
万字推演Elasticsearch修炼方法,从炼气到元婴
后端·elasticsearch·面试
INGNIGHT4 小时前
440 · 背包问题(三)(无限次数)
算法·leetcode·动态规划
suhan4 小时前
【数据结构】七、查找:1.查找的概念、线性结构查找(顺序、折半(二分)、插值、稠密、分块、倒排)
数据结构·算法·排序算法
极客 - L U4 小时前
卡尔曼滤波从零到精通
c语言·数据结构·单片机·嵌入式硬件·mcu
killerbasd4 小时前
总结 10.26
算法
深圳安锐科技有限公司4 小时前
从成像尺度到亚像素解算:变焦视觉位移监测如何让远近断面都稳
图像处理·人工智能·深度学习·算法·计算机视觉·系统架构·结构健康监测
zhippt_10145 小时前
图转PPT实测:截图和课件图片怎么变成可编辑幻灯片
人工智能·面试·powerpoint
devilnumber5 小时前
Redis 数据类型 + 项目落地场景(面试版,全面、实用,后端常用)
数据库·redis·面试