leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal
代码实现:给定一个中序遍历和后序遍历怎么构造出这颗树!(假定树中没有重复的数字)
因为没有规定是左小右大的树,所以我们随意画一颗数,来进行判断应该是满足题意的。
3
/ \
2 4
/\ / \
1 6 5 7
中序遍历:.
后序遍历:.
我们知道后序遍历的最后一个肯定就是根了。然后在前序遍历中找到这个根,左边的就是左子树(记作subv1),右边的就是右子树(记作subv1)。在后序遍历中,前面的几个对应左子树的后序遍历(记作subv2),接下去的几个对应右子树的后序遍历(记作subv2),注意,右子树的后序遍历系系数因为3的不同位置所以要减一。
这样我们就可以分成两组的前序遍历和后序遍历的子数组了。然后递归调用返回,一个给根的左,一个给根的右。则有如下代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
if (inorder.size() == ) return NULL;
int rootval = postorder.back();
TreeNode *root = new TreeNode(rootval); vector<int> subv11, subv12, subv21, subv22;
bool flag = true; for (int i = ; i < inorder.size(); ++i)
{
if (inorder[i] == rootval) flag = false;
if (flag && inorder[i] != rootval)
{
subv11.push_back(inorder[i]);
subv21.push_back(postorder[i]);
}
else if (!flag && inorder[i] != rootval)
{
subv12.push_back(inorder[i]);
subv22.push_back(postorder[i - ]);
}
}
root -> left = buildTree(subv11, subv21);
root -> right = buildTree(subv12, subv22); return root;
}
};
如上,我是没次迭代的时候将数组分割成两部分,然后再对两部分分别递归求解。理论上应该是正确的。但是估计每次开辟新的vector存子数组用的空间一次一次递归用的空间太大了。以至于Memory Limit Exceeded
由上面的提示,我们知道,要达到好的效果那就不能一直开辟新的vector了,应该在原来的数组里操作,那么要达到和开辟新数组一样的效果就要用同时传入一些下标了。
中序遍历:3.
后序遍历:3.
同样的道理,首先我们要根据后序遍历的最后一个在中序遍历中分左右两部分,然后再确定后序遍历中相应部分的下标的起始位置。对每个数组我们传入两个下标参数,开始start和结束end下标。其中inorder的start记作is,end记作ie,postorder的start记作ps,end记作pe。
初始,中序遍历的开始为0,结束为inorder.size()-1.同理可以后序的也是类似。
每一次分割,中序遍历的126的开始为前一次开始is,结束为根节点3标号rootIndex-1,相应的后序遍历开始为前一次开始ps,因为长度要喝中序相同,所以结束为ps+(rootIndex-1-is)。
中序遍历的的开始为根节点3标号rootIndex+1,结束为前一次的结束ie。我们可以确定结束为pe-1,因为长度相同,所以开始为pe-1-(ie-(rootIndex+1)).
那么就有代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *fun105(vector<int> &inorder, int is, int ie, vector<int> &postorder, int ps, int pe)
{
if (is > ie || ps > pe || ie - is != pe - ps) return NULL;
TreeNode *root = new TreeNode(postorder[pe]);
int rootIndex, rootval = root -> val;
for (int i = ; i <= ie; ++i)
{
if (inorder[i] == rootval)
rootIndex = i;
} root -> left = fun105(inorder, is, rootIndex - , postorder, ps, ps + (rootIndex--is));
root -> right = fun105(inorder, rootIndex + , ie, postorder, pe - - (ie-(rootIndex+)), pe - ); return root;
}
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
if (inorder.size() == ) return NULL;
return fun105(inorder, , inorder.size() - , postorder, , postorder.size() - );
}
};
主要的难点就是下标的控制,特别是利用长度来控制后序遍历的结束下标和起始下标。
错误的尝试:本来没有用已知长度去求后序遍历的下标,而是直接根据rootInex的下标去找后序遍历的起始,后面发现因为rootIndex在第二次迭代的时候前面已经有一个之前的根了,所以和后序遍历的下标对应就会差1,所以是错误的。迫不得已,就用已知的长度相等和已知后序遍历的某些确定下标去求未知下标了。
leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal的更多相关文章
- [Leetcode Week14]Construct Binary Tree from Inorder and Postorder Traversal
Construct Binary Tree from Inorder and Postorder Traversal 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/pr ...
- Java for LeetCode 106 Construct Binary Tree from Inorder and Postorder Traversal
Construct Binary Tree from Inorder and Postorder Traversal Total Accepted: 31041 Total Submissions: ...
- leetcode -day23 Construct Binary Tree from Inorder and Postorder Traversal & Construct Binary Tree f
1. Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder travers ...
- (二叉树 递归) leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- [LeetCode] 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- C#解leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树 C++
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- 【leetcode】Construct Binary Tree from Inorder and Postorder Traversal
Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...
随机推荐
- 【CTO辩论】移动创业大军:谁斗争or变更代理
众创时代.英雄辈出. 但千军万马过独木桥,竞争厮杀也异常残酷.有人说,这个时代不宜创业,由于技术门槛高了.推广难度高了.盈利模式没了.创业变重了.玩法变了...... 也有人说,时势造英雄.天时地利人 ...
- Java内存模型-jsr133规范介绍(转)
最近在看<深入理解Java虚拟机:JVM高级特性与最佳实践>讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范. 系统的看了jsr 133规范的前面几 ...
- 查询(Query)和标识(Identify)
查询(Query)和标识(Identify) 相关文章:RESTful API URI 设计的一些总结. 问题场景:删除一个资源(Resources),URI 该如何设计? 应用示例:删除名称为 iP ...
- JavaScript语言核心之词法结构
编程语言的词法结构是一套基础性规则,用来描述如何使用这门语言来编写程序.作为语法的基础,它规定了诸如变量名是什么样的.怎么写注释,以及程序语句之间如何分割的等规则. 1.1字符集 JavaScript ...
- jaxb和dozer简介
一.jaxb是什么 JAXB是Java Architecture for XML Binding的缩写.可以将一个Java对象转变成为XML格式,反之亦然. 我们把对象与关系数据库之间 ...
- Javascript学习2 - Javascript中的表达式和运算符
原文:Javascript学习2 - Javascript中的表达式和运算符 Javascript中的运算符与C/C++中的运算符相似,但有几处不同的地方,相对于C/C++,也增加了几个不同的运算符, ...
- iOS开发- 拨打电话总结
关于iOS应用拨打电话, 我所知道的有3种办法, 详细例如以下: 一.利用openURL(tel) 特点: 直接拨打, 不弹出提示. 而且, 拨打完以后, 留在通讯录中, 不返回到原来的应用. //拨 ...
- Poj 3517 And Then There Was One Joseph核心问题
基本上纯Joseph核心问题,只是第一步多一件.m. 然后你就可以用获得的递推公式: Win(n) 代表n当个人的中奖号码, 然后,Win(n)必须相等Win(n-1).当一个人将在下一次删除队列. ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- LinkedBlockingQueue多线程测试
public class FillQueueThread extends Thread { private Queue queue; public FillQueueThread(Queue queu ...