当前位置: 首页 > article >正文

力扣889:根据先序和后序遍历构造二叉树

给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。

如果存在多个答案,您可以返回其中 任何 一个。

示例 1:

输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]

示例 2:

输入: preorder = [1], postorder = [1]
输出: [1]

上述例子用该代码模拟过程:

  1. 首先进入函数 constructFromPrePost,因为 preorderSize 不为 0,所以为根节点分配内存空间,并设置根节点的值为 preorder[0],即 1,此时 root->val = 1root->left 和 root->right 都初始化为 NULL

  2. 然后因为 preorderSize > 1,进入内部的构建子树逻辑。开始遍历后序遍历数组找先序遍历数组中第二个元素(也就是 2)的位置,找到后假设 idx 为 2(因为在后序遍历数组中 2 是第三个元素,索引为 2)。

  3. 接着递归构建左子树,调用 constructFromPrePost(preorder + 1, idx + 1, postorder, idx + 1),这里相当于传入先序遍历数组的 {2, 4, 5}(从第二个元素开始,长度为 idx + 1 = 3)和后序遍历数组的 {4, 5, 2}(从开头开始,长度为 idx + 1 = 3)来构建以 2 为根节点的左子树。

  4. 之后判断 idx + 2 < preorderSize,这里 idx + 2 = 4,小于 preorderSize = 7,所以要构建右子树。调用 constructFromPrePost(preorder + idx + 2, preorderSize - 2 - idx, postorder + idx + 1, postorderSize - 2 - idx),即传入先序遍历数组的 {3, 6, 7}(从 idx + 2 = 4 开始,长度为 preorderSize - 2 - idx = 7 - 2 - 2 = 3)和后序遍历数组的 {6, 7, 3}(从 idx + 1 = 3 开始,长度为 postorderSize - 2 - idx = 7 - 2 - 2 = 3)来构建以 3 为根节点的右子树。

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* constructFromPrePost(int* preorder, int preorderSize, int* postorder, int postorderSize) {
    // 如果先序遍历数组大小为0,说明没有节点,返回空指针,表示空树
    if (preorderSize == 0) {
        return NULL;
    }

    // 为根节点分配内存空间
    struct TreeNode *root = malloc(sizeof(struct TreeNode));

    // 设置根节点的值为先序遍历数组的第一个元素
    // 因为先序遍历的顺序是根节点、左子树、右子树,所以第一个元素就是根节点的值
    root->val = preorder[0];

    // 初始化根节点的左子树指针为空
    root->left = NULL;

    // 初始化根节点的右子树指针为空
    root->right = NULL;

    // 如果先序遍历数组大小大于1,说明除了根节点还有其他节点,需要进一步构建子树
    if (preorderSize > 1) {
        int idx;

        // 遍历后序遍历数组,找到先序遍历数组中第二个元素(即根节点的左子树的根节点在先序遍历中的值)
        // 在后序遍历数组中的位置
        // 因为后序遍历的顺序是左子树、右子树、根节点,所以先序遍历的第二个元素一定在左子树的后序遍历结果中
        for (int i = 0; i < postorderSize; i++) {
            if (postorder[i] == preorder[1]) {
                idx = i;
                break;
            }
        }

        // 递归构建根节点的左子树
        // 先序遍历数组从第二个元素开始,长度为idx + 1
        // 后序遍历数组从开头开始,长度为idx + 1
        root->left = constructFromPrePost(preorder + 1, idx + 1, postorder, idx + 1);

        // 如果idx + 2小于先序遍历数组大小,说明存在右子树,需要递归构建右子树
        if (idx + 2 < preorderSize) {
            // 先序遍历数组从idx + 2开始,长度为先序遍历数组大小减去2再减去idx
            // 后序遍历数组从idx + 1开始,长度为后序遍历数组大小减去2再减去idx
            root->right = constructFromPrePost(preorder + idx + 2, preorderSize - 2 - idx, postorder + idx + 1, postorderSize - 2 - idx);
        }
    }

    // 返回构建好的根节点指针,通过这个指针可以访问整个构建好的二叉树
    return root;
}


http://www.kler.cn/a/394683.html

相关文章:

  • Linux系统常用操作与命令指南
  • 利用编程语言和脚本编写技术,实现自动化渗透测试和安全工具的开发
  • 深度学习神经网络在机器人领域应用的深度剖析:原理、实践与前沿探索
  • 【AI日记】24.11.14 复习和准备 RAG 项目 | JavaScript RAG Web Apps with LlamaIndex
  • SQL 中 BETWEEN AND 用于字符串的理解
  • nginx配置负载均衡详解
  • Spring Boot与Quartz定时任务集成:深入指南
  • Ubuntu中使用纯命令行进行Android开发
  • 【SQL】一文速通SQL
  • Spring Boot驱动的电子商务平台开发
  • 【go从零单排】SHA256 Hashes加密
  • 【已解决】git push一直提示输入用户名及密码、fatal: Could not read from remote repository的问题
  • 使用ensp配置单臂路由、静态路由,实现PC互相通信。
  • golang 实现比特币内核:从公钥创建wallet地址
  • 【缓存策略】你知道 Write Through(直写)这个缓存策略吗?
  • MySQL 的主从复制数据同步
  • 生成式GPT商品推荐:精准满足用户需求
  • 斯坦福iDP3——改进3D扩散策略以赋能人形机器人的训练:不再依赖相机校准和点云分割(含源码解析)
  • 计算机毕业设计Python+大模型农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop
  • STM32系统的GPIO原理与结构
  • Python爬虫项目 | 一、网易云音乐热歌榜歌曲
  • 基于混沌加密的遥感图像加密算法matlab仿真
  • SQL 分组查询中的非聚合列要求及实例解析
  • JavaScript调用系统自带的打印页面
  • 云服务器端口开放
  • MATLAB保存多帧图形为视频格式