⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)

news2025/5/18 19:52:07

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

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]

提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

题解:

我们使用递归分治思想,因对于所给中序和前序,可通过前序序列确定第一个节点,再通过此节点在中序序列中的位置进而确定左右子树各自的中序序列,之后再通过其确定左右子树各自的前序序列,以此可进行递归处理;
同时注意某子树的中序序列长度和前序序列长度必为相等,可依据此性质确定递归时inorder数组和preorder数组下标起点终点该如何选择;
递归即对每个子树的中序和后序序列分别按照上述思想处理即可;

代码:

/**
 * 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) {
//         // 哈希表维护中序顺序,从而判断两元素之间方向关系
//         Map<Integer,Integer> map = new HashMap<>(); 
//         for(int i=0;i<inorder.length;i++){
//             map.put(inorder[i],i);
//         }

//         // 建造节点依靠先序,中序作为验证判断,从而选择l或r方向延申
//         // 初始化第一个位置,因其为确定且唯一
//         TreeNode res = new TreeNode(preorder[0]);
//         TreeNode temp = res;

//         // 其余元素需要加入中序判断
//         for(int i=1;i<preorder.length;i++){
//             int level = map.get(preorder[i]);
//             if(level > map.get(temp.val)){
//                 // 每次都叫node_new,但是分配区域不会回收
//                 // 只是名字被另一片区域剥夺,但因使用指针已经连接好,故不会混淆
//                 TreeNode node_new = new TreeNode(preorder[i]);
//                 temp.right = node_new;
//                 temp = temp.right;
//             }
//             else{
//                 // 同上 区别是若遍历到的节点在temp右方则必定temp加入此点后向right移动
//                 // 若在temp左方 需等待 因可能右方还有节点 
//                 // 当然也存在右方无节点情况 此时则需要判断下一节点是否仍为temp的left
//                 // 若是 则temp向left移动
//                 if(temp.left == null){
//                     TreeNode node_new = new TreeNode(preorder[i]);
//                     temp.left = node_new;
//                 }
//                 else{
//                     temp = temp.left;
//                     // 回溯未处理情况
//                     i--;
//                 } 
//             }
//         }

//         return res;
//     }
// }


// 递归法
class Solution {
    Map<Integer,Integer> map = new HashMap<>(); 
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 哈希表维护中序顺序,从而判断两元素之间方向关系
        for(int i=0;i<inorder.length;i++){
            map.put(inorder[i],i);
        }

        return ToBuildTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
    }

    public TreeNode ToBuildTree(int[] preorder,int[] inorder,int preStart,int preEnd,
        int inStart,int inEnd){
        // 中序序列和先序序列长度必为相等,因此只需判断一个即可
        if(preStart > preEnd)
            return null;   // 对于递归设置一个终止条件即可

        // 根节点可立刻确定
        TreeNode res = new TreeNode(preorder[preStart]);

        // 此根在中序遍历中下标位置
        int inorder_pre = map.get(preorder[preStart]);

        // 运用每个子树的中序序列和其对应的前序序列长度相等的性质,可推断出左子树和右子树前序序列分界点
        int placeLeft = inorder_pre-1 - inStart;
        res.left = ToBuildTree(preorder,inorder,preStart+1,preStart+1+placeLeft,inStart,inorder_pre-1);
        int placeRight = inEnd - (inorder_pre+1);  
        res.right = ToBuildTree(preorder,inorder,preEnd-placeRight,preEnd,inorder_pre+1,inEnd);

        return res;
    }
}

结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

朋友圈程序全开源版源码,附带系统搭建教程

前台一键发布图文&#xff0c;视频&#xff0c;音乐。发布内容支持定位或自定义位置信息。支持将发布内容设为广告模式消息站内通知或邮件通知。支持其他用户注册,支持其他用户发布文章,管理自己的文章。拥有丰富的后台管理功能&#xff0c;一键操作。安装环境 Nginx ≥1.22 …

stm32——hal库学习笔记(外部中断)

一、什么是中断&#xff1f;&#xff08;了解&#xff09; 打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断 中断的作用和意义 中断的意义&#xff1a;高效处理紧急程序&#xff0c;不会一直占用CPU资源 S…

Android14 InputManager-InputManagerService环境的构造

IMS分为Java层与Native层两个部分&#xff0c;其启动过程是从Java部分的初始化开始&#xff0c;进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start&#xff08;&#xff09;函数完成启动 同其他系统服务一样&#xff0c;IMS在SystemServer中的ServerT…

浅谈加密算法(对称加密、非对称加密、混合加密、数字签名、哈希函数)

1、对称加密 对称加密只有一个密钥&#xff0c;直接使用这一个密钥对信息进行加密或解密。这样子就使得对称加密解密十分高效&#xff0c;计算量也相较于非对称加密小很多&#xff0c;适合有大量数据的场合。 密钥只有一个且他一定不能泄漏。由此分发密钥&#xff0c;讲这个密钥…

聚合支付,聚合系统,聚合程序或将成为主流

支付市场的变化对用户、代理商和运营商产生了重大影响。 随着政策监管的日益严格&#xff0c;支付行业逐渐朝着标准化和合理化的方向发展&#xff0c;日益增强其安全性。在这个背景下&#xff0c;聚合平台已经成为未来支付行业发展的重要趋势。特别是在“一机一码”政策实施后&…

三防平板丨平板终端丨加固平板丨户外勘测应用

随着科技的不断发展&#xff0c;现代勘测业也在不断升级。相较于传统的勘测设备&#xff0c;三防平板在户外勘测中有着广泛的应用。那么&#xff0c;三防平板在户外勘测中究竟有哪些优势呢&#xff1f; 首先&#xff0c;三防平板具备极强的防水、防尘、防摔能力。在野外勘测中&…

MyBatis---初阶

一、MyBatis作用 是一种更简单的操作和读取数据库的工具。 二、MyBatis准备工作 1、引入依赖 2、配置Mybatis(数据库连接信息) 3、定义接口 Mapper注解是MyBatis中用来标识接口为Mapper接口的注解。在MyBatis中&#xff0c;Mapper接口是用来定义SQL映射的接口&#xff0c;通…

十分钟利用springboot写电商支持多种优惠券规则,使用策略模式替代大量的if-else

前言 在开发电商折扣模块的时候经常会碰到各种优惠规则&#xff0c;那么就会碰到很多条件判断&#xff0c;冗余各种if-else的代码使得维护困难&#xff0c;此时就可以用策略模式来解决&#xff0c;替代大量的冗余判断条件代码&#xff0c;精简代码结构。 策…

建筑行业的重要工具—— 智慧工地管理平台(java源码)

系统定义&#xff1a; 智慧工地管理平台系统是一种集成了先进的信息技术、物联网技术、移动互联网技术等多种技术的工地管理系统。它能够对工地的整个生命周期进行全面的管理&#xff0c;包括工地的规划、设计、施工、监控、验收等各个环节。通过信息化手段&#xff0c;提高了工…

拯救者Legion Y9000K 2021H(82K6)原厂oem预装Win11系统镜像

lenovo联想拯救者Y9000K(82K6)原装出厂Windows11系统安装包下载&#xff0c;恢复出厂开箱状态 链接&#xff1a;https://pan.baidu.com/s/1DGWU7gctJerff6LJrgHD5w?pwdrbs5 提取码&#xff1a;rbs5 原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office…

C++从入门到精通 第十四章(STL容器)【下】

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

基础数据结构与相关C++ STL容器

文章目录 数组arrayvector 栈和队列dequestackqueue 堆heappriority_queue 链表listforward_list 树setmapmultisetmultimap 哈希表unordered_setunordered_mapunordered_multisetunordered_multimap 图 数组 array 不开口的连续线性空间&#xff0c;支持随机访问。 array是…

【C->Cpp】由C迈向Cpp(4)

目录 &#xff08;一&#xff09;内联函数 &#xff08;二&#xff09;关键字auto &#xff08;三&#xff09;范围for &#xff08;四&#xff09;nullptr 正文开始&#xff1a; &#xff08;一&#xff09;内联函数 宏定义&#xff1a; C的内联函数是在C语言宏的基础上提出…

怎样开发Apple Vision Pro应用?以应用开发者角度体验苹果的开发文档

▲ 搜索“大龙谈智能内容”关注公众号▲ 最近&#xff0c;苹果公司推出了革命性的产品Apple Vision Pro&#xff0c;全世界震惊。下边这个视频在社交网络上得到了大量转发&#xff1a; 在大家兴奋的围观之际&#xff0c;已经有人在规划能做些什么了。 有朋友问大龙有什么Vi…

妨碍做出正确决策的5种认知谬误

人类的大脑在极端情况下会呈现出不可理喻的一面&#xff0c;从而妨碍我们做出正确的决策。本文介绍了5种常见的认知谬误&#xff0c;识别并克服这些认知谬误&#xff0c;可以帮助我们更好的决策。原文: Want to Make Better Decisions? Avoid These 5 Cognitive Distortions 我…

Python中类创建和实例化过程

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 一、 type() 1、创建类的两种方式 方式一 class MyClass(object):def func(self,name):print(name)myc MyClass()print(MyClass, type(MyClass)) print(myc, type(myc))我们创建了一个名为MyClass的类&#xff0c;并实例化…

书生·浦语大模型实战营-第四课笔记

期待已久的微调课 一、Finetune 增量预训练和指令跟随是两种微调模式&#xff0c;即两种微调策略。 1&#xff09;增量预训练 投喂新的领域知识即可&#xff0c;例如书籍、文章、代码 2&#xff09;指令跟随 采用高质量对话和问答数据进行训练 二、LoRA与QLoRA 两…

35、IO进程线程/多线程实现文件读写20240221

一、使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源。 代码&#xff1a; #include<myhead.h> typedef struct //类型重定义结构体 {const char *src;const char *dest;int start…

vue3总结

1 setup 概述 setup是Vue3中一个新的配置项个函数, 包含数据、方法等&#xff0c;是组合api的“舞台”。 特点如下&#xff1a; setup函数返回的对象中的内容&#xff0c;可直接在模板中使用。setup中访问this是undefined。setup函数会在beforeCreate之前调用&#xff0c;它…

人工智能深度学习

目录 人工智能 深度学习 机器学习 神经网络 机器学习的范围 模式识别 数据挖掘 统计学习 计算机视觉 语音识别 自然语言处理 机器学习的方法 回归算法 神经网络 SVM&#xff08;支持向量机&#xff09; 聚类算法 降维算法 推荐算法 其他 机器学习的分类 机器…