LeetCode题练习与总结:从中序与后序遍历序列构造二叉树--106

一、题目描述

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

示例 1:

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

示例 2:

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

提示:

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

二、解题思路

  1. 后序遍历的最后一个元素是树的根节点。
  2. 在中序遍历中找到根节点的位置,可以将中序遍历分成左右两个子树。
  3. 根据中序遍历中左右子树的长度,可以将后序遍历也分成左右两个子树。
  4. 递归地对左右子树进行上述步骤,构建出整棵树。

三、具体代码

java 复制代码
class Solution {
    private Map<Integer, Integer> indexMap;

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        indexMap = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            indexMap.put(inorder[i], i);
        }
        return buildTree(postorder, 0, postorder.length - 1, inorder, 0, inorder.length - 1);
    }

    private TreeNode buildTree(int[] postorder, int postStart, int postEnd, int[] inorder, int inStart, int inEnd) {
        if (postStart > postEnd || inStart > inEnd) {
            return null;
        }

        int rootVal = postorder[postEnd];
        TreeNode root = new TreeNode(rootVal);
        int index = indexMap.get(rootVal);

        int leftSize = index - inStart;
        int rightSize = inEnd - index;

        root.left = buildTree(postorder, postStart, postStart + leftSize - 1, inorder, inStart, index - 1);
        root.right = buildTree(postorder, postStart + leftSize, postEnd - 1, inorder, index + 1, inEnd);

        return root;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 构建索引映射表 indexMap 需要 O(n) 的时间,其中 n 是中序遍历的长度。
  • 递归函数 buildTree 对于每个节点都会被调用一次,每次调用都会处理一个子树,子树的规模随层数减小而减小。在最坏的情况下,每次递归都会将问题规模减半,因此递归的深度为 O(log n),但由于每次递归都需要进行一些常数时间的操作,所以每次递归的时间复杂度为 O(1)。因此,整个递归过程的时间复杂度为 O(n)。
  • 综上,整个算法的时间复杂度为 O(n)。
2. 空间复杂度
  • 索引映射表 indexMap 需要存储 n 个元素,因此空间复杂度为 O(n)。
  • 递归调用栈的最大深度为树的高度,最坏情况下树完全不平衡,高度为 O(n),因此递归的最大空间复杂度为 O(n)。
  • 综上,整个算法的空间复杂度为 O(n)。

五、总结知识点

  1. 哈希表(HashMap):用于存储中序遍历中每个值对应的索引,以便快速查找根节点在中序遍历中的位置。

  2. 递归 :构建二叉树的过程是通过递归函数 buildTree 实现的,每次递归处理一个子树,直到子树为空。

  3. 二叉树的构建:理解二叉树的结构和构建过程,以及中序遍历和后序遍历的特点。

  4. 数组的索引操作:通过数组的索引来访问和操作数组中的元素,以及计算子数组的长度和位置。

  5. 树的节点定义 :使用 TreeNode 类来定义树的节点,每个节点包含值 val 和指向左右子节点的引用 leftright

  6. 函数的定义和调用 :定义了两个函数 buildTreebuildTree(int[] postorder, int postStart, int postEnd, int[] inorder, int inStart, int inEnd),并理解它们之间的调用关系。

  7. 边界条件的判断 :在递归函数中,首先检查递归的基本情况(即递归的终止条件),如果 postStart > postEnd || inStart > inEnd,则返回 null

  8. 分治思想:将大问题分解为小问题来解决,这里是根据中序遍历和后序遍历的特点,将问题分解为构建左右子树的问题。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

相关推荐
爱coding的橙子3 小时前
每日算法刷题 Day3 5.11:leetcode数组2道题,用时1h(有点慢)
算法·leetcode
Chase_Mos4 小时前
Spring 必会之微服务篇(1)
java·spring·微服务
小林学习编程6 小时前
SpringBoot校园失物招领信息平台
java·spring boot·后端
撸码到无法自拔6 小时前
docker常见命令
java·spring cloud·docker·容器·eureka
heart000_16 小时前
IDEA 插件推荐:提升编程效率
java·ide·intellij-idea
Dream it possible!7 小时前
LeetCode 热题 100_只出现一次的数字(96_136_简单_C++)(哈希表;哈希集合;排序+遍历;位运算)
c++·leetcode·位运算·哈希表·哈希集合
ŧ榕树先生7 小时前
查看jdk是否安装并且配置成功?(Android studio安装前的准备)
java·jdk
未来的JAVA高级开发工程师7 小时前
适配器模式
java
LUCIAZZZ7 小时前
JVM之内存管理(一)
java·jvm·spring·操作系统·springboot
D_aniel_7 小时前
排序算法-计数排序
java·排序算法·计数排序