【剑指offer】7 - 重建二叉树

题目描述
  • 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7,2,1,5,3,8,6} ,则重建二叉树并返回
  • 二叉树节点定义如下:
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) 
        : val(x), left(NULL), right(NULL) 
    {}
};
解题思路
  • 前序遍历顺序为:根 -> 左 -> 右
  • 中序遍历顺序为:左 -> 根 -> 右
  • 观察这两个遍历顺序,我们可以从前序中找到二叉树的根,然后在中序中将二叉树的左子树和右子树分出来
  • 如果我们对左子树,和右子树重复上面的操作,那么我们就可以通过递归来实现二叉树的重建
  • 下面我们举例说明上述过程:
    二叉树重建
  • 思路理清楚之后,我们就可以写代码了:
代码实现
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) 
{
    //若前序和后序序列有一个为空,则无法重建,返回空
    if(pre.empty() || vin.empty())
        return NULL;

    //前序的第一个节点为根
    TreeNode* root = new TreeNode(pre[0]);
    int i = 0; //用来记录后序中根的位置
    for(i= 0; i < vin.size() && vin[i] != pre[0]; i++);

    vector<int> lpre, rpre, lvin, rvin;
    int pre_i = 1;
    for(int j = 0; j < vin.size(); j++)
    {
        //左区间
        if(j < i)
        {
            lpre.push_back(pre[pre_i++]);
            lvin.push_back(vin[j]);
        }
        else if(j > i) //右区间
        {
            rpre.push_back(pre[pre_i++]);
            rvin.push_back(vin[j]);
        }
    }
    root->left = reConstructBinaryTree(lpre, lvin);
    root->right = reConstructBinaryTree(rpre, rvin);
    return root;
}

猜你喜欢

转载自blog.csdn.net/Aurora_pole/article/details/81626440