python实现二叉树的重建1 之由前序遍历和中序遍历重建
前言
此题是关于树的面试题目的常见题型,题目的含义很清晰,这个就不用多说了
解法
关于这道题的解法有很多不同的样式,通用的解法是这样的:
假如现在我们有如下两个遍历的情况
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 之由前序遍历和中序遍历重建相关推荐
- 通过前序遍历和中序遍历构建二叉树 python实现
前言 通过前序遍历和中序遍历构建二叉树的原理,主要是找前序遍历根节点在中序遍历中的位置,然后将二叉树而成左子树和右子树,然后依次进行这样的操作,思路还是比较简单的 代码 class Node:def ...
- 根据二叉树的前序遍历和中序遍历重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- python实现二叉树遍历(前序遍历、中序遍历、后序遍历)
python实现二叉树遍历(前序遍历.中序遍历.后序遍历) 在计算机科学中,二叉树是一种树数据结构,其中每个节点最多有两个子节点,称为左子节点和右子节点.使用集合理论概念的递归定义是(非空)二叉树是元 ...
- 根据二叉树前序遍历和中序遍历重建二叉树
剑指 Offer 07. 重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出 前序遍历 preorder = [3, ...
- 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树. 假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序{ ...
- 二叉树的前序遍历,中序遍历,后序遍历-详解-配套例题
二叉树作为数据结构中一种简单而且重要的数据结构,他的存储结构和算法都相对比较简单,因此他也显得特别重要,因为很多问题都可以抽象为二叉树的问题. 在这里我们对于二叉树的基本概念不做详细介绍,我们这里主要 ...
- 二叉树排序--简单明了(知道前序后续求中序..)
前序.中序.后序遍历的特性: 前序遍历: 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 中序遍历: 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 后序遍历: 1.后序遍历左子树 2 ...
- 二叉树的前序遍历,中序遍历,后序遍历学习 (原)
经验: 不要死记各个遍历节点的位置,将一个复杂的二叉树当作一个个小的二叉树学习前序遍历,中序遍历,后序遍历会更容易理解 转载于:https://www.cnblogs.com/gyrgyr/p/962 ...
- 已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法
二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或 ...
- Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)
文章目录 前序.中序.后序的含义 实例 Code (递归) 前序遍历 中序遍历 后序遍历 测试 Code (非递归) 前序.中序.后序的含义 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树 中 ...
最新文章
- 2015第27周一非结构化数据
- JAVA实现链表中倒数第K个节点问题(《剑指offer》)
- qpython numpy_Python-Numpy全面精简教程
- 微型计算机中被处理信息称为,2011海南省计算机等级考试试题 二级C试题考资料...
- 机器学习算法总结--GBDT
- 深入学习二叉树(三) 霍夫曼树
- 认识零信任安全网络架构
- Amazon SQS 消息队列服务
- android+word转html,word与html互转(1) -- word转html
- VS2010整合NUnit进行单元测试
- mysql 慢查询日志记录
- 为什么C#有委托,而Java没有?
- [译] TensorFlow 教程 #09 - 视频数据
- MapX从数据库读取数据形成新图层【转载】
- 【BZOJ】3495: PA2010 Riddle
- 如何制作很火的抖音配音?原来爆款短视频配音方法这么简单
- PHP毕业设计 学生PHP网站模板 PHP校园二手商品网站源码 PHP MYSQL大学生动态网站毕设作品 PHP毕设网页学生成品
- 【机器学习基石】感知机模型+PLA(二)
- 自然语言处理十大应用
- 老路MBA商学课|第001课:机会成本|放弃掉的鱼,是选择熊掌的代价?