【4】 重建二叉树
时间限制:1秒
空间限制:32768K
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
时间限制:1秒空间限制:32768K
本题知识点: 查找
vs2010调试代码块
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//**********************方法二:自己写的
//说明:之前是一直卡在容器的赋值assign上,assign(b,e)。 e的使用类似与end(),指向末尾的下一个元素
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in)
{
//建立根结点
if(!pre.empty() && !in.empty())
{
TreeNode *root;
int Numleft=0;
vector<int> preL,inL;
vector<int> preR,inR;
if( ( root=(TreeNode*)malloc(sizeof(TreeNode)) )==NULL )
{
printf("不能再分配空间!");
exit(0);
}
root->val=*(pre.begin());
//查找左子树、右子树元素个数
vector<int>::iterator iter1=in.begin(),
iter2=in.end();
for( ; iter1!=iter2 && *iter1!=*(pre.begin()); iter1++)
{
Numleft++;
}
preL.resize(Numleft);
preL.assign(pre.begin()+1, pre.begin()+Numleft+1);
inL.assign(in.begin(), in.begin()+Numleft);
root->left=reConstructBinaryTree(preL, inL);
preR.assign(pre.begin()+Numleft+1, pre.end());
inR.assign(in.begin()+Numleft+1, in.end());
root->right=reConstructBinaryTree(preR, inR);
return root;
}
else
return NULL;
}
void PrintBT(TreeNode* BT) //先序输出二叉树
{//
if(!BT)
return;
printf("%d->",BT->val);
PrintBT(BT->left);
PrintBT(BT->right);
}
int main()
{
vector<int> pretest1;
vector<int> intest1;
TreeNode* BT;
int n=3;
printf("输入n的个数:");
cin>>n;
printf("输入先序序列:");
for(int i=0; i<n; i++)
{
int temp;
cin>>temp;
pretest1.push_back(temp);
}
printf("输入中序序列:");
for(int i=0; i<n; i++)
{
int temp;
cin>>temp;
intest1.push_back(temp);
}
for(int i=0; i<n; i++)
{
printf("%d->",pretest1[i]);
}
cout<<endl;
for(int i=0; i<n; i++)
{
printf("%d->",intest1[i]);
}
cout<<endl;
BT=reConstructBinaryTree( pretest1, intest1);
PrintBT(BT);
}
方法一:
//2016/8/30更新
//创建重载函数
class Solution {
private:
//函数重载
struct TreeNode* reConstructBinaryTree(const vector<int> &pre, int Startpre, int Endpre,const vector<int> &in, int Startin, int Endin)
{
if(Startpre>Endpre || Startin>Endin) return NULL;
//建立根节点
struct TreeNode* root=new struct TreeNode(pre[Startpre]);
//找出分界点i
int i=Startin;
for(; i<=Endin && in[i]!=pre[Startpre] ; i++) ;
//建立左右子树
root->left=reConstructBinaryTree(pre,Startpre+1,Startpre+(i-Startin),in,Startin,i-1);
root->right=reConstructBinaryTree(pre,Startpre+(i-Startin)+1,Endpre,in,i+1,Endin);
return root;
}
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
struct TreeNode* root=reConstructBinaryTree(pre,0,pre.size()-1,in,0,in.size()-1);
return root;
}
};
方法三:
struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in)
{
if (pre.size() == NULL) return NULL;
TreeNode* root = new TreeNode(pre[0]); //创建根结点
int i;
for (i = 0; i < in.size() && in[i] != pre[0]; i++)
;
vector<int> pre_left, in_left,pre_right,in_right;
int pre_i = 1;
for (int j = 0; j < in.size(); j++)
{
if (j < i)
{
in_left.push_back(in[j]);
pre_left.push_back(pre[pre_i]);
pre_i++;
}
else if (j>i)
{
in_right.push_back(in[j]);
pre_right.push_back(pre[pre_i]);
pre_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())
{
TreeNode *root;
int Numleft=0;
vector<int> preL,inL;
vector<int> preR,inR;
if( ( root=(TreeNode*)malloc(sizeof(TreeNode)) )==NULL )
{
printf("不能再分配空间!");
exit(0);
}
root->val=*(pre.begin());
//查找左子树、右子树元素个数
vector<int>::iterator iter1=in.begin(),
iter2=in.end();
for( ; iter1!=iter2 && *iter1!=*(pre.begin()); iter1++)
{
Numleft++;
}
preL.resize(Numleft);
preL.assign(pre.begin()+1, pre.begin()+Numleft+1);
inL.assign(in.begin(), in.begin()+Numleft);
root->left=reConstructBinaryTree(preL, inL);
preR.assign(pre.begin()+Numleft+1, pre.end());
inR.assign(in.begin()+Numleft+1, in.end());
root->right=reConstructBinaryTree(preR, inR);
return root;
}
else
return NULL;
}
};
2016/8/30改进
避免了容器元素的复制,时间效率更高,空间节省。
/**
* 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()) return NULL;
struct TreeNode* root;
//调用递归构造函数
root=reConstructBinaryTreeHelp(pre,0,in,0,in.size()-1);
return root;
}
struct TreeNode* reConstructBinaryTreeHelp(const vector<int> &pre,int pos,const vector<int> &in, int begin, int end){
//递归结束条件
struct TreeNode* pNode=new struct TreeNode(pre[pos]); //构造根结点
if(begin>end) return NULL;
if(begin==end){
return pNode;
}
int mid=begin; //查找分界点
for(int i=begin; i<=end; i++){
if(in[i]==pre[pos])
{ mid=i;break;}
}
// if(begin<mid)
pNode->left=reConstructBinaryTreeHelp(pre,pos+1,in,begin,mid-1);
// if(mid<end)
pNode->right=reConstructBinaryTreeHelp(pre,pos+mid-begin+1,in,mid+1,end);
return pNode;
}
};