重建二叉树
- 参与人数:5402时间限制:1秒空间限制:32768K
- 算法知识视频讲解
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
我没有按照书上的做法来解,而是采用long型指针来存储地址,虽然很绕,但是可以熟悉指针的使用。牛客网使用的是64位编译器,故不能用int数组存地址,而要使用long型数组。
<pre name="code" class="cpp">// 4.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
using namespace::std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in) {
if (pre.size() <= 0 || in.size() <= 0) return NULL;
if (pre.size() != in.size()) return NULL;
int length = pre.size(); // 获得数组的长度
long* pPre = new long[length];
int i = 0;
for (vector<int>::iterator iter = pre.begin(); iter != pre.end(); iter++){
pPre[i] = (long)&(*iter);// *iter取迭代器中的内容,&(*iter)取该内容的地址,(long)&(*iter)把地址转化为long型
i++;
}
long* pIn = new long[length]; // 动态分配数组内存
i = 0;
for (vector<int>::iterator iter = in.begin(); iter != in.end(); iter++){
pIn[i] = (long)&(*iter);
i++;
}
TreeNode* root = ConstructCore(pPre, pPre + length - 1, pIn, pIn + length - 1);
// 释放堆上的内存,防止内存泄漏,并清空指针
delete[] pPre;
pPre = NULL;
delete[] pIn;
pIn = NULL;
return root;
}
private:
TreeNode* ConstructCore(long* pPreStart, long* pPreEnd, long* pInStart, long* pInEnd){
// 构建根节点
long rootValue = *(long*)pPreStart[0];
TreeNode* root = new TreeNode(rootValue);
root->left = root->right = NULL;
// 判断是否为递归的退出条件:前序是否到头、中序是否到头、前序与中序是否重合
if (pPreStart == pPreEnd || pInStart == pInEnd || pPreStart == pInStart){
return root;
}
// 在中序数组中找到根节点的位置
long* rootPosi = pInStart;
while (rootPosi <= pInEnd && *(long*)rootPosi[0] != rootValue){
rootPosi++;
}
// 检验是否在中序数组中找到根节点
if (rootPosi == pInEnd && *(long*)rootPosi[0] != rootValue){
// *(long*)rootPosi与*(long*)rootPosi[0]意义完全不同,*(long*)rootPosi是把数组的第一个元素到最后一个元素看成整体解除指针引用
//throw new exception("not found!");
return NULL;
}
// 中序数组中根节点据数组头部的距离
long leftLength = rootPosi - pInStart;
// 构建左子树的四个实参
long* pNewPreStartLeft = pPreStart + 1;
long* pNewPreEndLeft = pPreStart + leftLength;
long* pNewInStartLeft = pInStart;
long* pNewInEndLeft = pInStart + leftLength - 1;
// 构建右子树的四个实参
long* pNewPreStartRight = pPreStart + leftLength + 1;
long* pNewPreEndRight = pPreEnd;
long* pNewInStartRight = rootPosi + 1;
long* pNewInEndRigth = pInEnd;
if (leftLength > 0){
root->left = ConstructCore(pNewPreStartLeft, pNewPreEndLeft, pNewInStartLeft, pNewInEndLeft);
}
if (leftLength < pPreEnd - pPreStart){
root->right = ConstructCore(pNewPreStartRight, pNewPreEndRight, pNewInStartRight, pNewInEndRigth);
}
return root;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int arrPre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int arrIn[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
vector<int> pre(arrPre, arrPre + 8);
vector<int> in(arrIn, arrIn + 8);
Solution s;
TreeNode* result = s.reConstructBinaryTree(pre, in);
system("pause");
return 0;
}
第二次做:
/**
* 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* reConstructBinaryTree(vector<int> pre, vector<int> in) {
if ( pre.empty() || in.empty() || pre.size() != in.size() ) return NULL ;
int length = pre.size() ;
TreeNode* root = new TreeNode( pre[0] ) ;
int rootVal = pre[0] ;
int mid = 0;
for ( ; in[mid] != rootVal; ++ mid ) {
if ( mid > length) return NULL ;
}
vector<int> pre_left ;
vector<int> in_left ;
for ( int i = 0; i < mid; ++ i ) {
pre_left.push_back( pre[i + 1] ) ;
in_left.push_back( in[i] ) ;
}
vector<int> pre_right ;
vector<int> in_right ;
for ( int i = mid + 1; i < length; ++ i ) {
pre_right.push_back( pre[i] ) ;
in_right.push_back( in[i] ) ;
}
root -> left = reConstructBinaryTree( pre_left, in_left ) ;
root -> right = reConstructBinaryTree( pre_right, in_right ) ;
return root ;
}
};
第三次做:
/**
* 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* reConstructBinaryTree(vector<int> pre,vector<int> in) {
if ( pre.empty() || in.empty() || pre.size() != in.size() ) return NULL ;
TreeNode* root = new TreeNode( pre[0] ) ;
int rootVal = pre[ 0 ] ;
int mid = 0 ;
int length = pre.size() ;
for ( ; in[mid] != rootVal; ++ mid ) {
// if ( mid > length ) return NULL ;
}
vector<int> pre_left ;
vector<int> in_left ;
for ( int i = 0; i < mid; ++ i ) {
pre_left.push_back( pre[i + 1] ) ;
in_left.push_back( in[i] ) ;
}
vector<int> pre_right ;
vector<int> in_right ;
for ( int i = mid + 1; i < length; ++ i ) {
pre_right.push_back( pre[i] ) ;
in_right.push_back( in[i] ) ;
}
root->left = reConstructBinaryTree( pre_left, in_left ) ;
root->right = reConstructBinaryTree( pre_right, in_right ) ;
return root ;
}
};