前言

此题是关于树的面试题目的常见题型,题目的含义很清晰,这个就不用多说了

解法

关于这道题的解法有很多不同的样式,通用的解法是这样的:
假如现在我们有如下两个遍历的情况

preorder: [1, 2, 4, 5, 3, 6]
inorder: [4, 2, 5, 1, 6, 3]

那么我们建树的办法通常是

1.用先序遍历的第一个元素也就是1,作为root
2.然后在inorder中查找1的位置
3.然后将inorder以1分割成两半,一半表示左子树,一半表示右子树,这里就是[4, 2, 5]和[6, 3]
4.然后使用[2, 4, 5]和[4, 2, 5]去构建左子树,[3, 6]和[6, 3]去构建右子树

我们以此可以写出如下的解决办法:

# 树的定义
class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = None
def buildTree(self, preorder, inorder):if inorder:ind = inorder.index(preorder.pop(0))root = TreeNode(inorder[ind])root.left = self.buildTree(preorder, inorder[0:ind])root.right = self.buildTree(preorder, inorder[ind+1:])return root

如果我们考虑到不停的pop(0),这样效率不是很高的话,我们可稍微优化一下:

    def buildTree(self, preorder, inorder):""":type preorder: List[int]:type inorder: List[int]:rtype: TreeNode"""def build(preorder, inorder):if inorder:ind = inorder.index(preorder.pop())root = TreeNode(inorder[ind])root.left = build(preorder, inorder[ind+1:])root.right = build(preorder, inorder[:ind])return rootpreorder.reverse()inorder.reverse()return build(preorder, inorder)

这里我们先将列表翻转了,这样,我们弹栈的时候,就不会造成很多的列表元素的移动。
但是即使如此,我们考虑最坏的情况:这个树不是平衡的而是一颗只有左子树的斜树,那么,他的先序遍历和中序遍历是完全相反的,整个算法过程中进行第二步的查找过程时候所花费的时间为O(n^2),由于我们使用的递归的实现方法,所以空间复杂度也是O(n^2)

优化时间复杂度

我们可以省略在Inorder中查找这一步,不是找到1在inorder中的index,把数组分成几个部分,然后递归它们上,而是递归到全部剩下的数组,当你遇到1的时候就停止,具体的实现如下:

def buildTree(self, preorder, inorder):def build(stop):if inorder and inorder[-1] != stop:root = TreeNode(preorder.pop())root.left = build(root.val)inorder.pop()root.right = build(stop)return rootpreorder.reverse()inorder.reverse()return build(None)

其中当我们遇到了在inorder中遇到了stop时候,证明我们在这里树要开始“转向”了,即从左子树变成右子树了,所以我们继续接着上一次的stop来走

再优化空间复杂度

    def buildTree2(self, preorder, inorder):if len(preorder) == 0:return Nonei, j = 1, 0root = TreeNode(preorder[0])stack = [root]while i < len(preorder):node = TreeNode(preorder[i])tmp = Nonewhile stack and stack[-1].val == inorder[j]:tmp = stack.pop()j += 1if tmp:tmp.right = nodeelse:stack[-1].left = nodestack.append(node)i += 1return root

我们现在不使用递归了,而是直接使用栈来解决这个问题,我们从头到尾过一遍preorder,把过的元素存在栈中,如果发现preorder中有元素在inorder中出现了,就开始把栈中元素弹出来,之所以这样做,是因为好比已经建完了半边的树,现在要换半边继续建树了

参考

leetcode solution 1
leetcode solution 2

python实现二叉树的重建1 之由前序遍历和中序遍历重建相关推荐

  1. 通过前序遍历和中序遍历构建二叉树 python实现

    前言 通过前序遍历和中序遍历构建二叉树的原理,主要是找前序遍历根节点在中序遍历中的位置,然后将二叉树而成左子树和右子树,然后依次进行这样的操作,思路还是比较简单的 代码 class Node:def ...

  2. 根据二叉树的前序遍历和中序遍历重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  3. python实现二叉树遍历(前序遍历、中序遍历、后序遍历)

    python实现二叉树遍历(前序遍历.中序遍历.后序遍历) 在计算机科学中,二叉树是一种树数据结构,其中每个节点最多有两个子节点,称为左子节点和右子节点.使用集合理论概念的递归定义是(非空)二叉树是元 ...

  4. 根据二叉树前序遍历和中序遍历重建二叉树

    剑指 Offer 07. 重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出 前序遍历 preorder = [3, ...

  5. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树. 假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序{ ...

  6. 二叉树的前序遍历,中序遍历,后序遍历-详解-配套例题

    二叉树作为数据结构中一种简单而且重要的数据结构,他的存储结构和算法都相对比较简单,因此他也显得特别重要,因为很多问题都可以抽象为二叉树的问题. 在这里我们对于二叉树的基本概念不做详细介绍,我们这里主要 ...

  7. 二叉树排序--简单明了(知道前序后续求中序..)

    前序.中序.后序遍历的特性: 前序遍历: 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 中序遍历: 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 后序遍历: 1.后序遍历左子树 2 ...

  8. 二叉树的前序遍历,中序遍历,后序遍历学习 (原)

    经验: 不要死记各个遍历节点的位置,将一个复杂的二叉树当作一个个小的二叉树学习前序遍历,中序遍历,后序遍历会更容易理解 转载于:https://www.cnblogs.com/gyrgyr/p/962 ...

  9. 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

    二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...

  10. Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)

    文章目录 前序.中序.后序的含义 实例 Code (递归) 前序遍历 中序遍历 后序遍历 测试 Code (非递归) 前序.中序.后序的含义 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树 中 ...

最新文章

  1. 2015第27周一非结构化数据
  2. JAVA实现链表中倒数第K个节点问题(《剑指offer》)
  3. qpython numpy_Python-Numpy全面精简教程
  4. 微型计算机中被处理信息称为,2011海南省计算机等级考试试题 二级C试题考资料...
  5. 机器学习算法总结--GBDT
  6. 深入学习二叉树(三) 霍夫曼树
  7. 认识零信任安全网络架构
  8. Amazon SQS 消息队列服务
  9. android+word转html,word与html互转(1) -- word转html
  10. VS2010整合NUnit进行单元测试
  11. mysql 慢查询日志记录
  12. 为什么C#有委托,而Java没有?
  13. [译] TensorFlow 教程 #09 - 视频数据
  14. MapX从数据库读取数据形成新图层【转载】
  15. 【BZOJ】3495: PA2010 Riddle
  16. 如何制作很火的抖音配音?原来爆款短视频配音方法这么简单
  17. PHP毕业设计 学生PHP网站模板 PHP校园二手商品网站源码 PHP MYSQL大学生动态网站毕设作品 PHP毕设网页学生成品
  18. 【机器学习基石】感知机模型+PLA(二)
  19. 自然语言处理十大应用
  20. 老路MBA商学课|第001课:机会成本|放弃掉的鱼,是选择熊掌的代价?

热门文章

  1. 2022-2028年中国汽轮发电机行业市场深度分析及发展趋势分析报告
  2. vue实现文件上传功能
  3. javascript的知识总结
  4. 使用阿里云服务器安装docker,并用nginx示例
  5. 派生类参数初始化列表和基类构造函数顺序
  6. Maven 传递性依赖
  7. SpringBoot配置文件YAML配置注入(详解)
  8. TVM 各个模块总体架构
  9. Dockerfile构建实践
  10. 视频系列:RTX实时射线追踪(上)