(剑指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:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...
随机推荐
- 详解Ubuntu Server下启动/停止/重启MySQL数据库的三种方式(ubuntu 16.04)
启动mysql: 方式一:sudo /etc/init.d/mysql start 方式二:sudo service mysql start 停止mysql: 方式一:sudo /etc/init.d ...
- WPF TreeGrid的一种简单实现
前几天,各种坑爹的情况,导致不得不自己去动手实现带层级关系的Grid.之后翻了翻书,貌似说msdn和codeproject上有这么个例子,叫做TreeListView.这里就简单说下自己的思路,也许有 ...
- [HZOI 2016]我们爱数数
[HZOI 2016]我们爱数数 题目大意: 一张圆桌,每个位置按顺时针从\(1\)到\(n\)编号.有\(n\)个人,编号从\(1\)到\(n\).如果编号为\(i\)的人坐到了编号为\(i\)的位 ...
- PAT甲级1033. To Fill or Not to Fill
PAT甲级1033. To Fill or Not to Fill 题意: 有了高速公路,从杭州到任何其他城市开车很容易.但由于一辆汽车的坦克容量有限,我们不得不在不时地找到加油站.不同的加油站可能会 ...
- 使用Win2D在UWP程序中2D绘图(二)
绘制API 首先还是看一下前文的的示例: args.DrawingSession.DrawEllipse(155, 115, 80, 30, Colors.Black, 3); args.Dra ...
- mOByDiC E90C2600 EOBD/OBDII to RS232 gateway
http://www.ozenelektronik.com/downs/pdf/oe90c2600.pdf Features • Compatible with EOBD/OBDII standard ...
- C# 中的回车换行符
在 C# 中,我们用字符串 "\r\n" 表示回车换行符. string str = "第一行\r\n第二行"; 但是我们更推荐 Environment.New ...
- WPF, WPF Browser Application(XBAP) 和 Silverlight 的区别
由图可见,XBAP与WPF的区别是“受限的”:Silverlight与XBAP的区别是,不需要.NET Framework. 上星期與以前的同事爭論著究竟使用XBAP來開發XX用戶端 (為筆者之前開發 ...
- java获取指定日期之前或之后的时间
/** * 前/后?分钟 * * @param d * @param minute * @return */ public static Date rollMinute(Date d, int min ...
- Appium+python自动化9-SDK Manager
前言 SDK Manager到有哪些东西是必须安装的呢? 一.SDK Manager 1.双击打开SDK Manager界面