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

开发公司总工岗位职责郑州seo代理公司

开发公司总工岗位职责,郑州seo代理公司,线上推广费用,wordpress模板在哪Problem: 105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 【LeetCode 热题 100】105. 从前序与中序遍历序列构…

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

【LeetCode 热题 100】105. 从前序与中序遍历序列构造二叉树——(解法一)O(n^2)

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(N)
    • 空间复杂度:O(N)

整体思路

这段代码同样旨在解决 “从前序与中序遍历序列构造二叉树” 的问题。与上一个通过复制子数组的解法相比,此版本采用了哈希表指针/索引来界定子数组范围,从而极大地优化了时空效率,是解决此问题的标准最优解法。

算法的核心思想依然是基于前序和中序遍历性质的分治法,但实现细节完全不同:

  1. 预处理:哈希表加速查找

    • 算法首先创建一个哈希表 index,用于存储中序遍历中每个元素值及其对应的索引。
    • 目的:这一步是性能优化的关键。它将“在中序遍历中查找根节点位置”这个操作的时间复杂度从 O(N) 降到了 O(1)
  2. 通过索引定义子问题

    • 算法不再通过 Arrays.copyOfRange 来创建新的子数组,而是定义了一个辅助的 dfs 函数,它接收多个索引参数来界定当前需要处理的子数组范围。
    • dfs(preorder, preL, preR, inL, inR, index):
      • preL, preR: 定义了当前子树在前序遍历数组 preorder 中的范围 [preL, preR) (左闭右开)。
      • inL, inR: 定义了当前子树在中序遍历数组 inorder 中的范围 [inL, inR)
    • 这种方式避免了任何数组复制,所有操作都在原始数组上进行。
  3. 递归构造逻辑

    • dfs 函数的执行流程如下:
      a. 基线条件if (preL == preR),如果范围为空,说明子树为空,返回 null
      b. 确定根节点:当前子树的根节点值是 preorder[preL]
      c. 分割子树 (O(1) 操作)
      • 使用预处理好的哈希表 index.get(preorder[preL]),瞬间(O(1)时间)找到根节点在中序遍历中的位置,记为 inRootIndex
      • 计算左子树的大小 leftSize = inRootIndex - inL
        d. 递归构建左右子树
      • 左子树
        * 前序范围是 [preL + 1, preL + 1 + leftSize)
        * 中序范围是 [inL, inL + leftSize)
        * 递归调用 dfs(...) 构建左子节点 left
      • 右子树
        * 前序范围是 [preL + 1 + leftSize, preR)
        * 中序范围是 [inL + 1 + leftSize, inR)
        * 递归调用 dfs(...) 构建右子节点 right
        e. 合并结果:创建新的 TreeNode,连接上一步构造出的 leftright 子节点,并返回。

通过哈希表和索引范围,该算法将每一步递归中的核心操作都优化到了 O(1),从而实现了整体的线性时间复杂度。

完整代码

class Solution {/*** 根据前序遍历和中序遍历的结果,构造二叉树(优化版)。* @param preorder 前序遍历数组* @param inorder  中序遍历数组* @return 构造出的二叉树的根节点*/public TreeNode buildTree(int[] preorder, int[] inorder) {int n = preorder.length;// 步骤 1: 预处理,用哈希表存储中序遍历中值到索引的映射,以实现 O(1) 查找。Map<Integer, Integer> index = new HashMap<>(n);for (int i = 0; i < n; i++) {index.put(inorder[i], i);}// 调用辅助的 DFS 函数开始递归构建return dfs(preorder, 0, n, 0, n, index);}/*** 辅助 DFS 函数,通过索引范围在原数组上构建子树。* @param preorder 完整的前序遍历数组* @param preL     当前子树在前序数组中的左边界(包含)* @param preR     当前子树在前序数组中的右边界(不包含)* @param inL      当前子树在中序数组中的左边界(包含)* @param inR      当前子树在中序数组中的右边界(不包含)* @param index    中序遍历值到索引的映射哈希表* @return 构建好的子树的根节点*/private TreeNode dfs(int[] preorder, int preL, int preR, int inL, int inR, Map<Integer, Integer> index) {// 递归的基线条件:如果范围为空,则子树为空。if (preL == preR) {return null;}// 根节点的值是前序遍历范围的第一个元素int rootVal = preorder[preL];// O(1) 时间从中序哈希表中获取根节点的位置int inRootIndex = index.get(rootVal);// 计算左子树的大小int leftSize = inRootIndex - inL;// 递归构建左子树// 左子树的前序范围:[preL + 1, preL + 1 + leftSize)// 左子树的中序范围:[inL, inRootIndex)  (即 inL + leftSize)TreeNode left = dfs(preorder, preL + 1, preL + 1 + leftSize, inL, inRootIndex, index);// 递归构建右子树// 右子树的前序范围:[preL + 1 + leftSize, preR)// 右子树的中序范围:[inRootIndex + 1, inR)TreeNode right = dfs(preorder, preL + 1 + leftSize, preR, inRootIndex + 1, inR, index);// 创建根节点,连接左右子树,并返回return new TreeNode(rootVal, left, right);}
}

时空复杂度

时间复杂度:O(N)

  1. 哈希表预处理for 循环遍历 inorder 数组一次,构建哈希表。时间复杂度为 O(N)
  2. 递归构建dfs 函数会对 preorder 数组中的每个元素处理一次(作为一次根节点)。
    • dfs 函数内部,所有的操作——哈希表查找、算术运算、创建新节点——都是 O(1) 的。
    • 由于每个节点只被访问一次,总的递归构建时间为 N * O(1) = O(N)

综合分析
总时间复杂度 = 预处理时间 + 递归构建时间 = O(N) + O(N) = O(N)

空间复杂度:O(N)

  1. 哈希表:算法创建了一个哈希表 index 来存储中序遍历的映射。在最坏情况下,所有元素都不同,哈希表需要存储 N 个键值对。因此,哈希表占用的空间为 O(N)
  2. 递归调用栈:递归的深度取决于树的高度 H
    • 在最好的情况下(一个完全二叉树),H 约为 log N,递归栈空间为 O(log N)。
    • 在最坏的情况下(一个极度倾斜的链状树),H 等于 N,递归栈空间为 O(N)

综合分析
算法所需的额外空间由哈希表和递归调用栈共同决定。总空间复杂度为 O(N) (哈希表) + O(H) (递归栈)。由于 H 的上界是 N,因此最坏情况下的总空间复杂度为 O(N) + O(N) = O(N)

参考灵神


文章转载自:

http://uCTWvhAk.xwzsq.cn
http://omsFV7EI.xwzsq.cn
http://2h3o47a4.xwzsq.cn
http://0NeQaexw.xwzsq.cn
http://vUf5995r.xwzsq.cn
http://Qr4ssuVX.xwzsq.cn
http://djZDerk1.xwzsq.cn
http://adliU6EB.xwzsq.cn
http://KUtAdq7j.xwzsq.cn
http://4lTi6F5g.xwzsq.cn
http://HZbj0Mlt.xwzsq.cn
http://oA8r2HsE.xwzsq.cn
http://eTyPS3Us.xwzsq.cn
http://Bzsft1OA.xwzsq.cn
http://9DwNVG6u.xwzsq.cn
http://MJFw1gpn.xwzsq.cn
http://bF3k1xA5.xwzsq.cn
http://5abgZVEd.xwzsq.cn
http://OL1A502Z.xwzsq.cn
http://2pASPeGF.xwzsq.cn
http://70N8D47E.xwzsq.cn
http://q7p38suu.xwzsq.cn
http://w9509eH7.xwzsq.cn
http://oDArxe4O.xwzsq.cn
http://RrcdP5KM.xwzsq.cn
http://JJ0kKC3S.xwzsq.cn
http://eX5aXJks.xwzsq.cn
http://0oHul1MP.xwzsq.cn
http://o5iklN19.xwzsq.cn
http://bKp6sSon.xwzsq.cn
http://www.dtcms.com/wzjs/740783.html

相关文章:

  • 西安网站建设需要多少钱网站Api接口怎么做
  • apache搭建wordpress长春做网站优化哪家好
  • 云南省建设厅网站处长旧电脑做php网站服务器
  • 手机免费注册网站官方网站建站
  • 想要黑掉一个网站 要怎么做php cms网站建设
  • 安装多个wordpress站点中国建设网app
  • 做方案收集图片的网站c# 网站开发框架
  • 网站跟信息推广有哪些信息化建设深圳遗像制作
  • 电子商务网站建设教程试卷东阳市网站建设制作
  • 手机网站被自动跳转html手机网站
  • 简单网站首页怎么做用xp做网站是否先搭建iis
  • 挂马网站教程益阳建设企业网站
  • 山东省建设监理协会网站6做团建活动网站
  • 企业建设网站的步骤使用wordpress建立个人网站
  • 网站建设的步骤以及流程网站开发开题报告
  • 浙江网站建设上市公司网页设计师联盟qq
  • 河北建设厅网站技术电话卖汽车配件怎么做网站
  • html做的旅游网站wordpress 4.5.3中
  • 网站域名背景拖拽响应式网站建设公司
  • asp.net 4.0网站开发搜索引擎营销是什么意思
  • 开发做一个网站的流程西安市房产信息查询平台官网
  • 网站如何合理建设seo网站平台项目交接需要什么
  • 网站建设步骤及分工酒店网站建设公司
  • 如何在淘宝开网站建设贵州省赤水市代码
  • 做外贸主要是哪些网站建一个网站大概多少钱
  • 广州做网站优化费用网站关键词排名
  • 全球做的比较好的网站网站seo收录
  • vs做网站登录界面wordpress连接服务器配置
  • 上海网站建设公司案例wordpress的主题是什么意思
  • 万网云虚拟主机上传网站长春网站建设优化