
Leetcode 102题.从中序与后序遍历序列构造二叉树
发布日期:2021-05-08 11:10:45
浏览次数:11
分类:精选文章
本文共 2649 字,大约阅读时间需要 8 分钟。
题目
例如,给出
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]返回如下的二叉树:
3 / \ 9 20 / \ 15 7思路
从中序和后序生成原理可知,后序遍历中的最后一个元素即为root节点,则该节点对应到中序遍历中又把中序遍历划分为左右子树,这两个左右子树又反过来对应各自的后序遍历。(即元素3将中序遍历划分为[9]和[15,20,7]两个子树,这两个子树对应后序遍历又可以推出子树的root节点)。
分析可知,二叉树的构造存在重复的子问题,则可使用递归来解决问题。我们只需要通过后序遍历的最后一个元素,就可以通过中序定位该元素的左右子树,则左右子树又是一个由中序和后序遍历构造还原二叉树的过程。
给出的初步的思路(错解)过程:class Solution { public: unordered_mapmap;//通过键值对得到每个数的位置 TreeNode* buildTree(vector & inorder, vector & postorder) { if(inorder.empty()) return NULL; for(int i = 0; i < inorder.size(); i++){ map[inorder[i]] = i;//给出int值对应的位置 数值-位置(从0开始) } return build(inorder, postorder, 0 ,postorder.size()-1, 0, postorder.size()-1); } TreeNode* build(vector & inorder, vector & postorder, int rf, int lf, int rs, int ls) { if(rf > lf) return NULL; TreeNode *root = new TreeNode(postorder[ls]); int position = map[postorder[ls]]; root->left = build(inorder, postorder, rf, position-1, rs, position-1);//注意这里的rf rs不能用0代替!!! root->right = build(inorder, postorder, position+1, lf, rs+position, ls-1);//这里的rs不是position 他是每次在分类后的position位置叠加 return root; }};
首先要分析递归函数需要接受什么参数,中序和后序遍历向量肯定需要,而且在不断的分割向量时,需要明确新产生的中序和后序遍历,如果采用拷贝传递额外消耗了内存,依旧可以使用原始遍历,只要给出对应所在的位置即可,这样的话明确了传递2个向量,4个int确定位置(两个向量的首尾)。
第一次 :首先通过postorder
最后一个元素postorder.size()-1
,则在inorder
对应的position
划分为两个部分,那么两部分分别是[0,position-1
]和[position+1
,postorder.size()-1
]。对于第一次划分没有错。
注意:第一次划分的写法十分不严谨,因为在后序的划分中中序遍历的左子树起始位置不都是0,这就导致递归过程中的范围错误,使用递归必须明确通项写法!类似数学归纳法的通项!上面的写法并非通项带入到代码中肯定会产生错误,因为后序的中序遍历不会总是从0开始!!!!这里将是常犯错误一定要注意规避!
修改后的代码:
class Solution { public: unordered_mapmap;//通过键值对得到每个数的位置 TreeNode* buildTree(vector & inorder, vector & postorder) { if(inorder.empty()) return NULL; for(int i = 0; i < inorder.size(); i++){ map[inorder[i]] = i;//给出int值对应的位置 数值-位置(从0开始) } return build(inorder, postorder, 0 ,postorder.size()-1, 0, postorder.size()-1); } TreeNode* build(vector & inorder, vector & postorder, int rf, int lf, int rs, int ls) { if(rf > lf) return NULL; TreeNode *root = new TreeNode(postorder[ls]); int position = map[postorder[ls]]; root->left = build(inorder, postorder, rf, position-1, rs, position-1+rs-rf);//注意这里的rf rs不能用0代替!!! root->right = build(inorder, postorder, position+1, lf, rs+position-rf, ls-1);//这里的rs不是position 他是每次在分类后的position位置叠加 return root; }};
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月08日 03时45分21秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
(C++11/14/17学习笔记):线程启动、结束,创建线程多法、join,detach
2019-03-04
leetcode 14 最长公共前缀
2019-03-04
做做Java
2019-03-04
C++并发与多线程(一)
2019-03-04
java一些基本程序
2019-03-04
vue-依赖-点击复制
2019-03-04
LeetCode 116填充每个节点的下一个右侧结点指针
2019-03-04
2021-4-28【PTA】【L2-1 包装机 (25 分)】
2019-03-04
Arduino mega2560+MPU6050利用加速度值控制舵机
2019-03-04
紫书——蛇形填数
2019-03-04
A Guide to Node.js Logging
2019-03-04
webwxbatchgetcontact一个神奇的接口
2019-03-04
Edge浏览器:你的的内核我的芯
2019-03-04
【考研英语-基础-简单句】简单句的核心变化_谓语情态
2019-03-04
Jetson AGX Xavier硬件自启动
2019-03-04
统计字符数
2021-05-07
JS数据类型的判断
2021-05-07
实现一个简易Vue(三)Compiler
2021-05-07
仿小米商城(上)
2021-05-07