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 ...
随机推荐
- JavaScript技巧&写法
原文:JavaScript技巧&写法 JavaScript技巧篇: 1>状态机 var state = function () { this.count = 0; this.fun = ...
- hdu 4407 Sum 容斥+当前离线
乞讨X-Y之间p素数,,典型的纳入和排除问题,列的求和运算总和的数,注意,第一项是最后一个项目数. 如果不改变到第一记录的答案,脱机处理,能保存查询,候,遇到一个操作1,就遍历前面的操作.把改动加上去 ...
- Pro Aspnet MVC 4读书笔记(4) - Working with Razor
Listing 5-1. Creating a Simple Domain Model Class using System; using System.Collections.Generic; us ...
- ASP.NET验证控件
在此过程中房间的收费制度时,.为了验证文本框是否为空.用户存在.合法等等.我们都要单独写代码.学习了ASP.NET的验证控件,省了非常多事. ASP.NET能够轻松实现对用户输入的验证. 让我们好好回 ...
- 【DataStructure】Some useful methods for arrays
Last night it took me about two hours to learn arrays. For the sake of less time, I did not put emph ...
- Service与Activity与交流AIDL
深圳旅游月.终于回来了,做了很多个月,这些天来的东西会慢慢总结出来的.今天,我们正在谈论的Service小东西:沟通. 固定通信的做法比较,基本上按照写模板可以实现. 1.Service与Activi ...
- JVM可支持的最大线程数(转)
摘自:http://sesame.iteye.com/blog/622670 工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题. ...
- JavaEE(6) - JMS消息选择和查看
1. JMS消息的类型.消息头和消息属性 消息类型: StreamMessage MapMessage TextMessage ObjectMessage BytesMessage JMS消息中的消息 ...
- JS常用方法总结,及jquery异步调用后台方法实例
//前台接收get参数值 function getQueryString(name) { var queryStrings = window.location.search.sp ...
- iis配置网址(主机名)
一直以来,常常弄不成功关于网址的问题. 今天查了下资料 首先,找到你的文件:C:\Windows\System32\drivers\etc的hosts文件,直接用记事本打开 # Copyright ( ...