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

Leetcode 106. 从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 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
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

思路:后序遍历是左右根,左右无法确定,只有根是一个节点,是能确定的,必然在后续数组的最右边。然后中序遍历是左右根,当根确定之后,虽然左右子树的具体情况不知道,但是知道左右子树的大体,然后把左右子树,继续当作一个树,继续遍历,知道最后一个节点不再是树,向上放回,递归构造。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        // 中序遍历是左中右,后序遍历是左右中,使用递归,用左右坐标来分割两个数组,每个小数组都是一个小树
        // 左右中,这是后序树的数组,那么这个子数组的最后一个元素一定是这个子树的根节点,然后中序序列里找
        // 左中右,找到中,就可以分割开左右子树,迭代分割,直到最小子树,无法分割
        return buildTreeHelper(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1);
    }

    public TreeNode buildTreeHelper(int[] inorder, int inStart, int inEnd,int[] postorder, int postStart, int postEnd) {
         if (inStart > inEnd || postStart > postEnd) {
            return null;
        }
        // 最后一个必是根节点
        int root = postorder[postEnd];
        int rootIndex = 0;
        // 得到根节点坐标
        while (true) {
            if (root == inorder[rootIndex]) {
                break;
            }
            rootIndex++;
        }
        // 只有中序遍历知道左右子树的信息是不够的,还需要让后续遍历知道
        int leftLength = rootIndex - inStart;
        // 左子树的中序遍历数组起始就是父数组的起始,结束是根节点-1,后序遍历数组的起始就是父数组的起始,结束是父数组起始 + 左子树长度 - 1
        TreeNode left = buildTreeHelper(inorder, inStart, rootIndex-1, postorder, postStart, postStart + leftLength-1);
        // 右子树的中序遍历数组起始就是根节点+1,结束是父数组的结束,后序遍历数组的起始就是父数组的起始 + 左子树长度,结束是父数组的结束 - 1,减去的这个1就是根节点的长度
        TreeNode right = buildTreeHelper(inorder, rootIndex + 1, inEnd, postorder, postStart + leftLength, postEnd-1);
        // 然后构造返回
        return new TreeNode(root, left, right);
    }

}


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

相关文章:

  • MySQL的SQL书写顺序和执行顺序
  • 什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性
  • 深入理解接口测试:实用指南与最佳实践5.0(三)
  • 网页版五子棋——对战模块(服务器端开发②)
  • JavaScript高级程序设计基础(四)
  • 【C++】类与对象的基础概念
  • 计算机毕业设计之:基于微信小程序的中药材科普系统(源码+文档+讲解)
  • vue3/Element/Tabs 标签页的使用与详解
  • 基于Qt5.12.2开发 MQTT客户端调试助手
  • Go基础学习04-变量重声明;类型转换;类型断言;Unicode代码点;类型别名;潜在类型
  • MobileNetV2: Inverted Residuals and Linear Bottlenecks
  • vue2和vue3页面加自定义水印(组件化)
  • 【计算机网络 - 基础问题】每日 3 题(二十)
  • SpringBoot的应用
  • 现代桌面UI框架科普及WPF入门1
  • Mac电脑上最简单安装Python的方式
  • Java:文件操作
  • [spring]用MyBatis XML操作数据库 其他查询操作 数据库连接池 mysql企业开发规范
  • WPF入门教学十四 命令与ICommand接口
  • OpenAI GPT o1技术报告阅读(5)-安全性对齐以及思维链等的综合评估与思考
  • Servlet入门:服务端小程序的初试(自己学习整理的资料)
  • R包:gplots经典热图
  • CentOS中使用Docker运行mysql并挂载本地目录
  • 滚雪球学SpringCloud[9.3讲]:微服务监控与运维详解
  • redis 快速入门
  • Serilog文档翻译系列(五) - 编写日志事件