剑指Offer刷题(4)

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路:
首先,回忆一下二叉树的概念。 二叉树
介绍一个例子:
前序遍历为abdefgc
中序遍历为 debfgac
后续遍历为edgfbca
现在我们考虑重建二叉树:
1.先求出根节点(前序序列第一个元素)。
2.将根节点带入到中序遍历序列中求出左右子树的中序遍历序列。
3.通过左右子树的中序序列元素集合带入前序遍历序列可以求出左右子树的前序序列。
4.左右子树的前序序列第一个元素分别是根节点的左右儿子
5.求出了左右子树的4种序列可以递归上述步骤
代码如下:
/**
 * Definition for binary tree
 * struct TreeNode<span style="font-family: Arial, Helvetica, sans-serif;"> {</span>
 *     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;
        }
        //定义Node节点并其求根节点;
        int root = pre[0];
        TreeNode* node = new TreeNode(root);
        vector<int>::iterator it;
        //1.求左右子树的遍历序列;
        vector<int> preLeft, preRight, inLeft, inRight;
            //(1).求根节点在中序遍历序列中的位置;
        vector<int>::iterator i;
        for(it = in.begin(); it != in.end(); it++) {
            if(root == *it) {
                i = it;
            }
        }
            //(2).求左右子树的中序遍历子序列;
        int k = 0;
        for(it = in.begin(); it != in.end(); it++) {
            if(k == 0) {
                inLeft.push_back(*it);
            }
            else if(k == 1) {
                inRight.push_back(*it);
            }
            else {}
            if(it == i) {
                k = 1;
            } 
        }
            //(3).求左右子树的前序遍历子序列;
        k = 0;
        vector<int>::iterator ite;
        for(it = pre.begin()+1; it != pre.end(); it++) {
            for(ite = inLeft.begin(); ite != inLeft.end(); ite++) {
                if(*it == *ite) {
                    preLeft.push_back(*it);
                    k = 1;
                }
            }
            if(k == 0) {
                preRight.push_back(*it);
            }
            k = 0;
        }
        //根据遍历序列求出跟的左右节点;
        node->left = reConstructBinaryTree(preLeft,inLeft);
        node->right = reConstructBinaryTree(preRight,inRight);
        //返回节点地址;
        return node;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值