【4】重建二叉树

【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;
    }
};

测试通过图片:

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值