python数据结构剑指offer-重建二叉树
例题
描述
给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,5,3,6,7}和中序遍历序列{4,2,5,1,6,3,7},则重建出如下图所示。
解决思路
因为先序遍历根中序遍历是保存在数组中的,所以我们需要利用数组的性质,而不是上来就利用二叉树的性质,刚开始我是按照二叉树来做的,直到我失败了无数次之后,看到了函数的传入值是两个list,我好像参悟了什么,又好像没参悟透,然后我就看大佬的代码,看了好多次,手动运行了好多次,始终一知半解,好像懂了,又没懂,然后我就去看了评论区,发现大多数人和我一样,都刚开始没看懂,我才知道,我不是一个人在战斗。然后一气之下不做了,直接玩游戏,刷视频,好好的睡了一觉,起来之后,一切豁然开朗,拿到代码顺序读明白了,现在把这题的思路写下来,帮助后来人。
利用二叉树的性质将数组分类
根据先序遍历,将根节点找到,是1
然后在根据中序遍历,找到左子树和右子树
这个时候根据左右子树,再将先序遍历划分为三部分
至此,二叉树已经处理完毕,现在在处理他的位置
利用数组的位置处理
先序遍历找位置
处理一棵二叉树,肯定要先进入根,所以我们先在先序遍历里面找到根以及根的位置
找到根之后,我们肯定要接着找根,先处理左子树,在处理右子树,那么我们这个时候在找到左子树的根
左子树的根找到了,我们现在先找右子树的根,先不去处理左子树,一会一起处理,因为处理他们的办法是相同的
会发现右子树的根的位置恰好是根节点+左子树的长度
中序遍历找位置
根据先序遍历,我们在中序遍历里面找一下位置
我们可以找到中序遍历中根的位置
因为我们在先序遍历里面已经确定了一下左右子树根的位置,这个时候我们只需要在中序遍历里面确定他们的长度即可
从这我们可以知道左子树的长度为3,根节点的位置,右子树的长度为3,那么我们根据数组的性质,是不是可以推导以下推论:
- 左子树长度+根长度 = 数组总长-右子树长度
- 左子树的边界=0 ~ root-1(因为数组是从0开始计数,所以正好是0-2)
- 右子树的边界=root+1 ~ 数组总长-1(因为数组的长度是按照数量来计算,但是数组是从0开始计数)
至此,我们总结一下,整理成一个表格
这个时候我们发现这样看得懂,但是如何系统化呢?
4. 根节点在先序遍历里面找
5. 长度在中序遍历里面找
得出这样两条解决,我们开始解决
从这里我们可以看出,左子树的左边界我们如果设成left,则右子树的根节点就为i-left+root+1:i-left为左子树的长度+根节点在先序遍历中的位置,这个时候仅仅是根节点根左子树的长度,在加1,就是右子树的根节点
这个时候我们完成了递归公式,但是递归有两要素,结束条件和递归公式,现在我们在找结束条件。
刚才我们是很多数据,这个时候我们采用分治的思想,看看只有两个节点的时候是什么情况
可以发现,当left>right的时候,象征这递归结束了,所以我们把left<right作为结束条件
至此,我们把重建二叉树的全流程结束了。
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:# write code heredef cur(root,left,right):if left > right:return# 先在先序遍历拿到根节点preroot = pre[root]# 创建根节点,方便下面递归使用node = TreeNode(pre[root])# 在找到根节点的位置i = in_dic[preroot]# 根据之前得到的公式,开始遍历node.left = cur(root + 1,left,i-1)node.right = cur(i- left + root + 1,i+1,right)return nodein_dic = {}# 哈希表使用中序遍历,这样好找I值for x,i in enumerate(vin):in_dic[i] = xreturn cur(0,0,len(vin)-1)
结论
做树做递归,可以先一步一步推导一下,推导了,也就有规律了,然后在运用分治法进行最小分治就可以解决
python数据结构剑指offer-重建二叉树相关推荐
- 剑指offer 重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 剑指offer 重建二叉树 python
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 样例 输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4, ...
- 算法leetcode|剑指 Offer 27. 二叉树的镜像|226. 翻转二叉树(rust很强)
文章目录 剑指 Offer 27. 二叉树的镜像|226. 翻转二叉树: 样例 1: 限制: 分析 题解 rust go c++ java python 原题传送门:https://leetcode. ...
- 《LeetCode力扣练习》剑指 Offer 27. 二叉树的镜像 Java
<LeetCode力扣练习>剑指 Offer 27. 二叉树的镜像 Java 一.资源 题目: 请完成一个函数,输入一个二叉树,该函数输出它的镜像. 例如输入: 4 / 2 7 / \ / ...
- 剑指offer07.重建二叉树
剑指offer07重建二叉树 题目 : 输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点. 假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 示例 : Input: preo ...
- 【LeetCode】剑指 Offer 34. 二叉树中和为某一值的路径
[LeetCode]剑指 Offer 34. 二叉树中和为某一值的路径 文章目录 [LeetCode]剑指 Offer 34. 二叉树中和为某一值的路径 package offer;import ja ...
- 【LeetCode】剑指 Offer 27. 二叉树的镜像
[LeetCode]剑指 Offer 27. 二叉树的镜像 文章目录 [LeetCode]剑指 Offer 27. 二叉树的镜像 一.递归法 二.辅助栈(或队列) 一.递归法 根据二叉树镜像的定义,考 ...
- JZ27 [剑指 Offer 27] 二叉树的镜像
二叉树的镜像 Category Difficulty Likes Dislikes lcof Easy (79.61%) 311 - 请完成一个函数,输入一个二叉树,该函数输出它的镜像. 例如输入: ...
- python数据结构剑指offer-从尾到头打印链表
例题 描述 输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回). 如输入{1,2,3}的链表如下图: 返回一个数组为[3,2,1] 0 <= 链表长度 <= 1000 ...
最新文章
- mysql行级锁实例,PHP – MySQL行级锁定示例
- 1.2-shell结构以及执行
- 正确返回Unicode码点大于0xFFFF的字符串长度
- UE4学习-4.25版本Possess无法继承、UNavigationSystem命名空间找不到的解决方法
- Subsequence Hate CodeForces - 1363B(前缀和+dp)
- linux uefi无法启动文件,解决UEFI安装无法启动的问题
- UI实用素材模板|天气应用app的ui设计
- SQL Server2012内存性能计数器和内存DMV的变化
- qt 语言设置乱码_QT中文乱码与国际化支持
- css--小米商城----logo与home图标切换
- Campass + Scss ,让我们更优雅的编写CSS
- 台式计算机的显卡,台式电脑显卡天梯图-台式机显卡性能排名
- DCFNET:用于视觉跟踪的判别相关滤波器网络
- 用python爬取今日头条上的图片_Python爬虫:抓取今日头条图集
- edge 此项内容已下载并添加到 Chrome 中。_比肩迅雷的下载神器大盘点
- 我辛辛苦苦做了一个月的项目,组长年底用来写了晋升PPT
- 如何修改app在模拟器上的名字
- android拓展笔记本,有道笔记Android版上线,拓展移动终端产品布局
- 钉钉开放平台API对接第一讲
- JSOI 2015 送礼物
热门文章
- ubuntu16.04下出现登陆不进去
- Vue.js - Day4
- js (jQuery) 之 取值
- python中字符串(str)的常用处理方法
- Java设计模式--策略模式
- 《数据分析实战 基于EXCEL和SPSS系列工具的实践》一3.2 用“逐步推进法”推测需要的数据...
- Android图形---Graphics(概要)
- 使用ASP.NET AJAX Control Toolkit中的NoBot控件拒绝垃圾发布程序 【转载】
- 第一篇 mybatis的简介
- 基于FPGA实现的高速串行交换模块实现方法研究