(剑指Offer)面试题6:重建二叉树
题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
二叉树的定义如下:
struct BinaryTreeNode{
int val;
BinaryTreeNode* left;
BinaryTreeNode* right;
BinaryTreeNode(int x):val(x),left(NULL),right(NULL){}
};
思路:
在二叉树的先序遍历序列中,第一个数总是数的根结点的值,后面依次是是左子树结点的值、右子树结点的值;
在二叉树的中序遍历序列中,根节点位于序列中间,根节点左边为左子树,右边为右子树。
根据上述信息,我们可以:
先通过先序遍历序列找到根节点,
然后在中序遍历序列中找到根节点,这样就可以确定左子树和右子树。
接着再回到先序遍历序列中找到左子树和右子树,重复上述步骤(递归)。
代码:
struct BinaryTreeNode{
int val;
BinaryTreeNode* left;
BinaryTreeNode* right;
BinaryTreeNode(int x):val(x),left(NULL),right(NULL){}
};
BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){
int rootValue=startPreorder[0];
BinaryTreeNode* root=new BinaryTreeNode(rootValue);
if(startPreorder==endPreorder && startInorder==endInorder)
return root;
// else
// throw std::exception("Invalid Input.\n");
int* rootInorder=startInorder;
while(rootInorder!=endInorder && *rootInorder!=rootValue)
++rootInorder;
// if(rootInorder==endInorder && *rootInorder!=rootValue)
// throw std::exception("Invalid Input.\n");
int leftLength=rootInorder-startInorder;
int* leftPreOrderEnd=startPreorder+leftLength;
if(leftLength>0)
root->left=ConstructCore(startPreorder+1,leftPreOrderEnd,startInorder,rootInorder-1);
int rightLength=endPreorder-startPreorder-leftLength;
if(rightLength>0)
root->right=ConstructCore(leftPreOrderEnd+1,endPreorder,rootInorder+1,endInorder);
return root;
}
BinaryTreeNode* Construct(int* preOrder,int* inOrder,int length){
if(preOrder==NULL || inOrder==NULL || length<=0)
return NULL;
return ConstructCore(preOrder,preOrder+length-1,inOrder,inOrder+length-1);
}
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1
AC代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* construct(const vector<int> &pre,int startPre,int endPre,const vector<int> &in,int startIn,int endIn){
int rootValue=pre[startPre];
TreeNode* root=new TreeNode(rootValue);
if(startPre==endPre && startIn==endIn)
return root; int rootIndex=startIn;
while(rootIndex<=endIn && in[rootIndex]!=rootValue)
rootIndex++; int leftLength=rootIndex-startIn;
if(leftLength>0)
root->left=construct(pre,startPre+1,startPre+leftLength,in,startIn,rootIndex-1);
int rightLength=endPre-startPre-leftLength;
if(rightLength>0)
root->right=construct(pre,startPre+leftLength+1,endPre,in,rootIndex+1,endIn); return root;
} struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
int len=pre.size();
if(len<=0)
return NULL;
return construct(pre,0,len-1,in,0,len-1);
}
};
(剑指Offer)面试题6:重建二叉树的更多相关文章
- 剑指offer面试题6 重建二叉树(c)
- 剑指offer面试题6 重建二叉树(java)
注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 package com.xsf.SordF ...
- 剑指Offer:面试题6——重建二叉树(java实现)
问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不包含重复的数字. 例如: 输入:前序{1,2,4,7,3,5,6,8},中序{4,7,2,1 ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- 剑指Offer - 九度1385 - 重建二叉树
剑指Offer - 九度1385 - 重建二叉树2013-11-23 23:53 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的 ...
- 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)
题目:输入某二叉树的前序遍历和中序遍历的结果.请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...
- 剑指offer第二版-7.重建二叉树
描述:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树.假设前序遍历或中序遍历的结果中无重复的数字. 思路:前序遍历的第一个元素为根节点的值,据此将中序遍历数组拆分为左子树+root+右子树,前序遍 ...
- 剑指offer【04】- 重建二叉树(java)
题目:重建二叉树 考点:树 题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6, ...
- 剑指offer(4)重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 剑指offer——面试题8:二叉树的下一个节点
// 面试题8:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...
随机推荐
- ref和out的用法和区别。
关于ref和out的用法和区别在网上已经有很多的解释,这里只不过是写下对于我而说比较容易理解的解释. ref和out都可以用来在函数中返回数据,类似于c++中指针. 参数 Ref Out 是否一定需要 ...
- poj——1986 Distance Queries
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 14392 Accepted: 5066 ...
- 让新版Chrome支持本地跨域请求调试
1.创建一个Chrome的启动快捷方式: 2.右键点击快捷方式属性,然后在目标路径后面,添加以下参数: --disable-web-security --user-data-dir="e:\ ...
- NOIP初赛前一日记
2018年10月12日,早晨7:25于机房. 早晨的鄞中,晨风还有点清冷.看着电脑上翻遍的资料,心里实在是有一种说不出的感觉. 说出来也算是丢脸——作为浙江选手,我为了NOIP2018的初赛,停课了一 ...
- android 传递 类对象 序列化 Serializable
public class Song implements Serializable { /** * */ private static final long serialVersionUID = 64 ...
- [BZOJ4521][CQOI2016]手机号码(数位DP)
4521: [Cqoi2016]手机号码 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 875 Solved: 507[Submit][Status ...
- HDU 5514 Frogs(容斥原理)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5514 [题目大意] m个石子围成一圈,标号为0~m-1,现在有n只青蛙,每只每次跳a[i]个石子, ...
- Arab Collegiate Programming Contest 2012 J- Math Homework
思路:由于只有1-6这几个数,而这几个数的最小公倍数是60,所以只需要求出60以内有多少满足条件的数即可. 再就是求出对于给定的n,求出60的倍数.然后就是怎样求的问题了. 首先可以写成如下形式: ...
- zoj 3261 逆向并查集+离线处理
题意:给出一些点,每个点有权值,然后有一些边,相连.无向的.然后有一些操作 链接:点我 query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大) desto ...
- asp.net 去除数据中带有的html标签
1,在控制器中实现去除html标签的静态方法 //去除html标签 public static string ReplaceHtmlMark(object Contents) { string Htm ...