★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树

  • 106.从中序与后序遍历序列构造二叉树
    • :star:思路分析
    • 递归解法
  • 105. 从前序与中序遍历序列构造二叉树
    • 递归解法

---------------🎈🎈题目链接🎈🎈-------------------

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

在这里插入图片描述

⭐️思路分析

后序数组: 左 右 中
中序数组: 左 中 右
以后序数组的最后一个元素(即为根节点)为切割点,先切中序数组,
再根据中序数组的左长度,反过来再切后序数组的左和右。
一层一层切下去,每次后序数组最后一个元素就是节点元素。

在这里插入图片描述

递归解法

在这里插入图片描述
⭐️⭐️⭐️⭐️⭐️⭐️
1. 如果数组大小为0,说明是空节点,return null
2. 如果不为空,那么取后序数组的最后一个节点
3. 找到后序数组最后一个节点 在中序数组中的位置 作为切割点
4. 切割中序数组,切成中序左数组 和 中序右数组
5. 根据中序左数组的长度,切割后序数组,切成后序左数组和后序右数组
6. 递归处理左区间和右区间

时间复杂度O(N)
空间复杂度O(N)
采用了【左闭右闭】——只要一直保持一致就行

/**
 * 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) {
        //1.如果数组为空 那么就返回null
        if(inorder.length ==0 || postorder.length==0){
            return null;
        }
        return helper(inorder, postorder, 0, inorder.length-1, 0,postorder.length-1);
        //

    }
    public TreeNode helper(int[] inorder, int[] postorder, int inorderBegin, int inorderEnd, int postorderBegin, int postorderEnd){
        if(postorderBegin > postorderEnd){
            return null;
        }
        // 采用左闭右闭
        //2.如果不为空, 那么就取后序数组的最后一个元素
        int rootval = postorder[postorderEnd];
        TreeNode root= new TreeNode(rootval);

        //3.切割中序数组 得到对应中序数组中rootval所在的位置  进而得到中序左数组 中序右数组
        int midIndex;
        for(midIndex = inorderBegin; midIndex<=inorderEnd; midIndex++){
            if(inorder[midIndex] == rootval){
                break;
            }
        }
        int leftInorderBegin = inorderBegin;  // 中序左数组开头
        int leftInorderEnd = midIndex-1;      // 中序左数组结尾
        int rightInorderBegin = midIndex+1;    // 中序右数组开头
        int rightInorderEnd =  inorderEnd;     // 中序右数组结尾

        //4.根据中序左数组 切割后序数组,得到后序左数组 后序右数组
        int leftPostorderBegin = postorderBegin;                 // 后序左数组开头
        int leftPostorderEnd = postorderBegin + midIndex -inorderBegin -1;         // 后序左数组结尾
        int rightPostorderBegin = leftPostorderEnd+1;           // 后序右数组开头
        int rightPostorderEnd = postorderEnd-1;                  // 后序右数组结尾

        //5.递归处理左子树和右子树
        root.left = helper(inorder, postorder, leftInorderBegin, leftInorderEnd, leftPostorderBegin, leftPostorderEnd);
        root.right = helper(inorder, postorder, rightInorderBegin, rightInorderEnd, rightPostorderBegin, rightPostorderEnd);
        return root;
    }
}

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

递归解法

⭐️⭐️⭐️⭐️⭐️⭐️
接受参数int[ ] preorder, int[ ] inorder, preorder的开始,preorder的结束,inorder的开始,inorder的结束
1. 如果数组大小为0,说明是空节点,return null
2. 从前序的第一个得到根节点root
3. 根据midval 在中序数组inorder中 寻找切割点midindex
4. 对中序数组inorder进行切割 :中序左(begin/end) 中序右(begin/end)
5. 根据分化结果,对前序数组preorder进行切割 :前序左(begin/end) 前序右(begin/end)
6. 进行左右子树构建递归

/**
 * 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[] preorder, int[] inorder) {
        // 采用左闭右闭
        if(preorder.length == 0) return null;
        return helper(preorder, inorder, 0, preorder.length-1, 0, inorder.length-1);
    }
    public TreeNode helper(int[] preorder, int[] inorder, int preorderBegin, int preorderEnd, int inorderBegin, int inorderEnd){
        // 接受参数int[] preorder, int[] inorder, preorder的开始,preorder的结束,inorder的开始,inorder的结束

        // 1.如果数组大小为0,说明是空节点,return null
        if(preorderBegin > preorderEnd){
            return null;
        }

        // 2.从前序的第一个得到根节点root
        int midval = preorder[preorderBegin];
        TreeNode root = new TreeNode(midval);

        // 3. 根据midval 在中序数组inorder中 寻找切割点midindex
        int midindex;
        for(midindex = inorderBegin; midindex<=inorderEnd; midindex++){
            if(inorder[midindex] == midval){
                break;
            }
        }

        // 4.对中序数组inorder进行切割 :中序左(begin/end) 中序右(begin/end)
        int inorderLeftBegin = inorderBegin;
        int inorderLeftEnd = midindex-1;
        int inorderRightBegin =midindex+1;
        int inorderRightEnd = inorderEnd;

        // 5.根据分化结果,对前序数组preorder进行切割 :前序左(begin/end) 前序右(begin/end)
        int preorderLeftBegin = preorderBegin+1;
        int preorderLeftEnd = preorderLeftBegin + midindex-inorderBegin-1;
        int preorderRightBegin = preorderLeftEnd+1;
        int preorderRightEnd = preorderEnd;

        // 进行左右子树构建递归
        root.left = helper(preorder, inorder, preorderLeftBegin,preorderLeftEnd, inorderLeftBegin, inorderLeftEnd); //左
        root.right = helper(preorder, inorder, preorderRightBegin,preorderRightEnd, inorderRightBegin, inorderRightEnd); //右
        return root;

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/412102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型推理加速技术:计算加速篇

原文&#xff1a;大语言模型推理加速技术&#xff1a;计算加速篇 - 知乎 目录 简介 Transformer和Attention 瓶颈 优化目标 计算加速 计算侧优化 KVCache Kernel优化和算子融合 分布式推理 内存IO优化 Flash Attention Flash Decoding Continuous Batching Page…

嵌入式学习第二十一天!(线程)

线程&#xff1a; 1. 基本概念&#xff1a; 线程&#xff1a;线程是一个轻量级的进程&#xff0c;位于进程空间内部&#xff0c;一个进程中可以创建多个线程 2. 线程创建&#xff1a; 线程独占栈空间&#xff0c;文本段、数据段和堆区与进程共享 3. 线程调度&#xff1a; 与进程…

Tomcat 下部署若依单体应用可观测最佳实践

实现目标 采集指标信息采集链路信息采集日志信息采集 RUM 信息会话重放 即用户访问前端的一系列过程的会话录制信息&#xff0c;包括点击某个按钮、操作界面、停留时间等&#xff0c;有助于客户真是意图、操作复现 版本信息 Tomcat (9.0.81)Springboot(2.6.2)JDK (>8)DDT…

2024年软件测试路线,不同等级应具备的基本能力(总结)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试的正确…

大数据可视化的设计规范,全面剖析,很实用。

大数据可视化的设计规范需要考虑到数据量大、复杂度高、数据类型多样等特点。以下是一份常见的大数据可视化设计规范&#xff0c;供您参考&#xff1a; 设计原则 简单易用&#xff1a;保证用户操作简单、直观&#xff0c;降低用户认知负担。数据准确&#xff1a;保证数据准确…

数据可视化引领智慧工业新时代

在智慧工业的大潮中&#xff0c;数据可视化崭露头角&#xff0c;以其直观、清晰的方式赋能工业生产&#xff0c;为智慧工业的高效运转提供了强有力的支持。下面我就以可视化从业者的角度&#xff0c;简单聊聊这个话题。 数据可视化首先在智慧工业的生产监控中大显身手。通过将…

4-Bean的循环依赖

Bean的循环依赖 循环依赖指的是依赖闭环的问题 解决 首先我们来实例化A&#xff0c;实例化A时并没有处理依赖注入&#xff0c;因此会得到半成品A。有了半成品A&#xff0c;它会被封装成一个ObjectFactory&#xff0c;并且把它放入第三个缓存区singletonFactories中。 接下来要…

tmux的使用方法

1. tmux的定义 我&#xff1a;什么是tmux&#xff1f; GPT&#xff1a;tmux&#xff08;terminal multiplexer&#xff09;是一个强大的终端复用器&#xff0c;它允许用户在一个终端窗口中创建、访问和控制多个会话。使用tmux&#xff0c;你可以在一个窗口中打开多个终端会话&…

苍穹外卖 -- day11 - Apache ECharts- 营业额统计- 用户统计- 订单统计- 销量排名Top10

苍穹外卖-day11 课程内容 Apache ECharts 营业额统计 用户统计 订单统计 销量排名Top10 功能实现&#xff1a;数据统计 数据统计效果图&#xff1a; 1. Apache ECharts 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#x…

docker 常用指令(启动,关闭,查看运行状态)

文章目录 docker 常用指令启动 docker关闭 docker查看 docker的运行状态 docker 常用指令 启动 docker systemctl start docker关闭 docker systemctl stop docker查看 docker的运行状态 systemctl status docker如下图所示&#xff1a; 表示docker正在运行中

【Vue】

什么是Vue Vue是一款用于构建用户界面的JavaScript框架&#xff0c;它基于标准HTML、CSS和JavaScript构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助开发者高效地开发用户界面。Vue是一个JS库&#xff0c;无依赖其他JS库&#xff0c;直接引入一个JS文…

数据可视化--了解数据可视化和Excel数据可视化

目录 1.1科学可视化&#xff1a; 可视化是模式、关系、异常 1.2三基色原理&#xff1a; 三基色:红色、绿色和蓝色 1.3Excel数据可视化 1.3.1 excel数据分析-13个图表可视化技巧 1.3.2 excel数据分析-28个常用可视化图表&#xff08;video&#xff09; 1.3.3Excel可视化…

适配器模式(Adapter Pattern) C++

上一节&#xff1a;原型模式&#xff08;Prototype Pattern&#xff09; C 文章目录 0.理论1.组件2.类型3.什么时候使用 1.实践1.基础接口和类2.类适配器实现3.对象适配器实现 0.理论 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允…

基于JAVA的就医保险管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

B站项目-基于Pytorch的ResNet垃圾图片分类

基于Pytorch的ResNet垃圾图片分类 数据集预处理 画图片的宽高分布散点图 import osimport matplotlib.pyplot as plt import PIL.Image as Imagedef plot_resolution(dataset_root_path):image_size_list []#存放图片尺寸for root, dirs, files in os.walk(dataset_root_pa…

提升Vue3应用效率的秘诀:深入比较ref与reactive!

ref 和 reactive 是 Vue3 中实现响应式数据的核心 API。ref 用于包装基本数据类型&#xff0c;而 reactive 用于处理对象和数组。尽管 reactive 似乎更适合处理对象&#xff0c;但 Vue3 官方文档更推荐使用 ref。 我的想法&#xff0c;ref就是比reactive好用&#xff0c;官方也…

【深度学习】Pytorch教程(十三):PyTorch数据结构:5、张量的梯度计算:变量(Variable)、自动微分、计算图及其可视化

文章目录 一、前言二、实验环境三、PyTorch数据结构1、Tensor&#xff08;张量&#xff09;1. 维度&#xff08;Dimensions&#xff09;2. 数据类型&#xff08;Data Types&#xff09;3. GPU加速&#xff08;GPU Acceleration&#xff09; 2、张量的数学运算1. 向量运算2. 矩阵…

Netty NIO 非阻塞模式

1.概要 1.1 说明 使用非阻塞的模式&#xff0c;就可以用一个现场&#xff0c;处理多个客户端的请求了 1.2 要点 ssc.configureBlocking(false);if(sc!null){ sc.configureBlocking(false); channels.add(sc); }if(len>0){ byteBuffer.flip(); 2.代码 2.1 服务端代码 …

mini-spring|定义标记类型Aware接口,实现感知容器对象

**前言&#xff1a;**如果我们想获得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等这些能力做一些扩展框架的使用时该怎么操作呢。所以我们本章节希望在 Spring 框架中提供一种能感知容器操作的接口&#xff0c;如果谁实现了这样的一个接口&#xff…

智慧城市与数字孪生:共创未来城市新篇章

一、引言 随着科技的飞速发展&#xff0c;智慧城市与数字孪生已成为现代城市建设的核心议题。智慧城市注重利用先进的信息通信技术&#xff0c;提升城市治理水平&#xff0c;改善市民生活品质。而数字孪生则通过建立物理城市与数字模型之间的连接&#xff0c;为城市管理、规划…