题目:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

假设输入的前序遍历和中序遍历结果中都不含重复的数字。

例如输入前序遍历序列{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:重建二叉树的更多相关文章

  1. 剑指offer面试题6 重建二叉树(c)

  2. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 package com.xsf.SordF ...

  3. 剑指Offer:面试题6——重建二叉树(java实现)

    问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不包含重复的数字. 例如: 输入:前序{1,2,4,7,3,5,6,8},中序{4,7,2,1 ...

  4. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  5. 剑指Offer - 九度1385 - 重建二叉树

    剑指Offer - 九度1385 - 重建二叉树2013-11-23 23:53 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的 ...

  6. 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)

    题目:输入某二叉树的前序遍历和中序遍历的结果.请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...

  7. 剑指offer第二版-7.重建二叉树

    描述:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树.假设前序遍历或中序遍历的结果中无重复的数字. 思路:前序遍历的第一个元素为根节点的值,据此将中序遍历数组拆分为左子树+root+右子树,前序遍 ...

  8. 剑指offer【04】- 重建二叉树(java)

    题目:重建二叉树 考点:树 题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6, ...

  9. 剑指offer(4)重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  10. 剑指offer——面试题8:二叉树的下一个节点

    // 面试题8:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. ...

随机推荐

  1. 我对于react-router路由原理的学习

    目录 react-router依赖基础--history react-router是如何实现URL与UI同步 一 react-router依赖基础--history history是一个独立的第三方j ...

  2. 推荐2本学习java书和PDF

    推荐2本学习java书和PDF下载地址 <深入理解Java虚拟机:JVM高级特性与最佳实践>共分为五大部分,围绕内存管理.执行子系统.程序编译与优化.高效并发等核心主题对JVM进行了全面而 ...

  3. 关于python安全性的问题

    收集总结了一下python安全方面的知识点以及近年来的相关漏洞,如果有需要修正或补充的地方,欢迎各位师傅的指出. 常见web漏洞在python中的示例. xss python下的xss其原理跟php是 ...

  4. RxSwift 系列(二)

    前言 Subject是一个代理,它既是Observer,也是Observable.因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其 ...

  5. 交叉编译OpenSSL

    <openssl简介>     SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输.Netscape公司在推出第一个Web浏览 ...

  6. manacher算法求最长回文子序列

    一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...

  7. POJ3233 Matrix Power Series 矩阵乘法

    http://poj.org/problem?id=3233 挺有意思的..学习到结构体作为变量的转移, 题意 : 给定矩阵A,求A + A^2 + A^3 + ... + A^k的结果(两个矩阵相加 ...

  8. 入门cout输出的格式(补位和小数精度)

    http://blog.csdn.net/gentle_guan/article/details/52071415   mark一下,妈妈再也不用担心我高精度不会补位了

  9. bzoj 2434 ac自动机

    ac自动机中,如果以trie中的节点为节点,(fail[i],i)为边,可以建立一颗树,该树有如下特点:“节点u是节点v的祖先 当且仅当 u代表的字符串是v代表的字符串的一个后缀”.(u代表的字符串是 ...

  10. VMware中网络设置之NAT

    当完成VMwareWorkStation安装之后,网络连接中会多出两个网络连接,分别是VMnet1和VMnet8,如下图所示: 整个机器的结构就可以抽象成:VMware虚拟机系统(虚拟网卡vmnet0 ...