【LeetCode经典题解】:从前序和中序遍历构建二叉树详解

【LeetCode经典题解】:从前序和中序遍历构建二叉树详解
在这里插入图片描述
🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:Java.数据结构
在这里插入图片描述


在这里插入图片描述

【前言】

二叉树构造是算法中递归分治思想的经典应用,而通过前序与中序遍历序列还原二叉树,更是力扣考察二叉树特性的高频题。前序“根左右”、中序“左根右”的遍历特性,是逐层确定根节点、划分左右子树的关键。本文将从递归分治思想出发,拆解该问题的实现逻辑,分析代码设计的核心细节。

文章目录:

一、从前序遍历和中序遍历构造二叉树

链接直达:从前序遍历和中序遍历构造二叉树


在这里插入图片描述

二、思路分析

根据递归分治思想:

前序遍历:根节点—>左子树—>右子树;找到前序序列的第一个元素就是根节点;中序遍历:左子树—>根节点—>右子树;找到根节点在中序序列中的位置,从而确定左子树和右子树;递归处理:重复上面的步骤,依次确定子树的根节点并构建子树,直至子树为空。

三、代码详解

1.代码分析

  • preorder:前序遍历数组;
  • inorder : 中序遍历数组;
  • 成员变量 preIndex : 用于记录前序遍历中当前根节点的索引 (通过通过全局递增依次取前序序列的根节点)
  • findVal 方法:查找根节点在中序序列中的索引rootIndex;
  • 递归方法buildTreeChild
递归终止条件:当 inbegin>inend ,说明当前子树无节点,返回null;构建根节点,取前序数组preIndex位置的元素作为根节点;划分左右子树,通过findVal方法找到根节点在中序序列中的索引rootIndex,inbegin ~ rootIndex-1为左子树,rootIndex+1 ~ inend为右子树

2.代码展示

publicint preIndex;publicTreeNodebuildTree(int[] preorder,int[] inorder){returnbuildTreeChild(preorder, inorder,0,inorder.length-1);}publicintfindVal(int[] inorder,int inbegin,int inend,int key){for(int i = inbegin;i<=inend;i++){if(inorder[i]==key){return i;}}return-1;}publicTreeNodebuildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){//递归终止条件:当前子树中序区间无节点if(inbegin>inend){returnnull;}//前序序列Index位置作为根节点TreeNode root =newTreeNode(preorder[preIndex]);//在中序序列中找到根节点的索引int rootIndex =findVal(inorder,inbegin,inend,preorder[preIndex]);//preIndex递增,指向下一个子树根节点 preIndex++;//递归左子树,范围:inbegin ~ rootIndex-1 root.left =buildTreeChild(preorder,inorder,inbegin,rootIndex-1);//递归左子树,范围:rootIndex+1 ~ inend root.right =buildTreeChild(preorder,inorder,rootIndex+1,inend);return root;}

【总结】

本文围绕前序+中序构建二叉树问题,解析了递归分治的解题思路:依托前序确定根节点,通过中序划分左右子树区间,再递归构建子树至区间为空。代码中用 prIndex 追踪前序根节点位置,借 findVal定位中序根节点索引完成边界划分,核心是对遍历特性的运用与递归终止条件的设置。此外,还可通过哈希表优化中序查找效率,该思路也为后序+中序构建二叉树等同类问题提供了参考。
在这里插入图片描述

Read more

【优选算法】(实战解析双指针的神奇奥秘)

【优选算法】(实战解析双指针的神奇奥秘)

🔥承渊政道:个人主页 ❄️个人专栏: 《C语言基础语法知识》《数据结构与算法》《C++知识内容》《Linux系统知识》《算法刷题指南》《测评文章活动推广》 ✨逆境不吐心中苦,顺境不忘来时路!✨🎬 博主简介: 引言:在编程学习的道路上,算法刷题无疑是绕不开的核心环节—它既是检验基础功底的"试金石",也是提升逻辑思维、应对求职面试、突破技术瓶颈的关键路径.但很多学习者都会陷入同样的困境:盲目刷了上百道题,遇到新题目依然无从下手:只会死记硬背题解,换个场景就无法灵活应用;不清楚刷题顺序,在难题中内耗,最终消磨了学习热情,半途而废.事实上,算法刷题从来不是"数量取胜:,而是"方法为王".很多人误以为刷题就是"多做就行",却忽略了背后的逻辑:算法的本质是解决问题的思维模式,刷题的核心目的,是通过刻意练习,掌握不同类型题目的解题思路、拆解技巧,

By Ne0inhk
解锁动态规划的奥秘:从零到精通的创新思维解析(6)

解锁动态规划的奥秘:从零到精通的创新思维解析(6)

解锁动态规划的奥秘:从零到精通的创新思维解析(6) 前言: 在动态规划的众多问题中,多状态DP问题是一个非常重要的类别。它的难点在于如何设计合适的状态表示和转移方程,从而高效地解决问题。 多状态DP的核心思想在于:针对问题的不同属性或限制条件,将状态表示扩展为多个维度,使得状态可以更加精确地描述问题的子结构。这种方法既可以帮助我们更好地分解问题,又能够在求解过程中保留更多的信息,从而为最终的结果提供完整的支持。 在实际应用中,多状态DP常用于解决路径规划、背包问题、字符串编辑、博弈问题等场景。例如,在路径规划问题中,我们可以通过增加状态的维度来描述位置、步数以及路径的某些限制条件;在资源分配问题中,我们可以通过扩展状态来考虑当前的资源利用率和历史决策。 本篇内容将聚焦于多状态DP问题的基本原理和解决方法,结合典型实例,逐步介绍从状态定义、转移方程设计到代码实现的完整过程。希望通过这一系列讲解,读者能够对多状态DP的理论和实践有更深入的理解,掌握其在解决实际问题时的技巧与方法。 今天小编就要开启动态规划的多状态dp问题的讲解了,希望我讲完几篇文章后,对屏幕后的你会有一定程度的

By Ne0inhk

Haversine 距离算法详解(零基础友好版)

作为算法领域的研究者,我会从用途、核心原理、前置知识、公式拆解、代码实现五个维度,给你讲清楚 Haversine 距离算法 —— 它是计算地球表面两点球面直线距离的经典算法,日常用的地图测距、打车软件预估里程,背后都有它的身影。 一、 算法的核心用途 我们生活的地球是一个近似球体,如果要计算两个地点(比如北京到上海)的 “直线距离”,不能直接用平面几何的勾股定理(因为地球表面是曲面)。 Haversine 算法的作用,就是基于两点的经纬度坐标,计算它们在地球球面上的最短距离(这个最短距离也叫大圆距离,即穿过球心的平面切割球面形成的圆弧长度)。 二、 必须掌握的前置知识 在理解公式前,先记住 3 个关键概念: 1. 经纬度的定义 * 纬度 (latitude):衡量地点南北位置,范围是 [-90°, 90°],赤道是 0°,北极是 90°N,南极是 90°S。

By Ne0inhk
Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案

Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 simplify 的适配 鸿蒙Harmony 实战 - 驾驭路径精简算法、实现鸿蒙端高性能地理足迹渲染与矢量图形优化方案 前言 在鸿蒙(OpenHarmony)生态的运动健康轨迹展示、高精度室内导航以及大规模矢量地图看板开发中,“路径性能”是决定用户滑动流畅度的核心红线。面对用户运动 1 小时产生的包含数万个(X, Y)坐标点的原始 GPS 序列。如果直接将其交给鸿蒙端的渲染层进行绘制,不仅会引发由于顶点(Vertices)过多导致的 GPU 负载饱和。更会由于频繁的坐标点内存申请(Memory Allocation),产生严重的 UI 掉帧与功耗飙升。 我们需要一种“去重存精、视觉无损”的几何精简艺术。 simplify 是一套专注于极致性能的 Douglas-Peucker 及其增强算法实现。它能瞬间将冗余的、

By Ne0inhk