剑指offer -重建二叉树

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

思路:
1.
前序遍历序列 prev { 1, 2, 4, 7, 3, 5, 6, 8 };
中序遍历序列 vin { 4, 7, 2, 1, 5, 3, 8, 6 };

2.
前序:根左右 : 前序往后走是先往左走, 左完了之后才是右
中序:左根右。 中序往上走是先往根走,
在此之前。需要明白:前序的第一个节点就是中序的根结点,所以: 1 的左边是其左子树 右边是其右子树

3.
从而得到了大概的粗略的左右子树,但毕竟仅仅由上面是无法知道1的左右子树是怎样的排列细节
接下来可以这样想:依靠上面的方式我得到了一个粗略的左右子树,那如果我将vin顺序表按前面得到的粗略的左右子树分为两个缩小的顺序表,再根据prev顺序表得到其下一个元素,这个元素对应到缩小后的vin中,不就可以再次得到一个缩小之后的左右子树吗?重复上面的3过程,类似于子问题,所以下面用递归实现。


#pragma once 
#include<iostream>
#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:
    TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
    {       
        size_t index = 0;
        return _reConstructBinaryTree(pre,vin,index);
    }
    TreeNode*  _reConstructBinaryTree(vector<int> pre, vector<int> vin,size_t& index)
    {
        if (index >= pre.size()||vin.size() == 0)    
        {
            return   NULL;
        }
        else
        {
            TreeNode *_root = new TreeNode(pre[index]);
            vector<int> vleft;
            vector<int> vright;
            int i = 0;       //在前序得到一个数,在中序找到对应的位置 i
            while (i < vin.size() && vin[i] != pre[index])
            {
                i++;
            }
            for (int j = 0; j < i; j++)
            {
                vleft.push_back(vin[j])  ;
            }
            for (int j = i+1; j<vin.size(); j++)
            {
                vright.push_back(vin[j]);
            }

            index++;
            _root->left = _reConstructBinaryTree(pre,vleft,index);
            _root->right = _reConstructBinaryTree(pre, vright, index);
            return _root;
        }

    }
};

void test()     
{
    int  pre[8] = { 1, 2, 4, 7, 3, 5, 6, 8 };
    vector<int> p(pre,pre+8);
    int  vin[8] = { 4, 7, 2, 1, 5, 3, 8, 6 };
    vector<int > v(vin,vin+8) ;
    Solution s;
    s.reConstructBinaryTree(p,v);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值