剑指offer4_重建二叉树_题解

重建二叉树

题目描述

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

示例1

输入

[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]

返回值

{1,2,5,3,4,6,7}

分析

方案一:递归算法

前序遍历数组 \(pre\) 的首元素就是二叉树的根节点,根据根节点的值在中序遍历数组 \(vin\) 中找到根节点的位置 \(i\) ,则在中序遍历中根节点位置 \(i\) 左边就是左子树的序列,根节点右边就是右子树的序列

设树一共有 \(n\) 个节点,下标从0开始,易知左子树的结点个数为 \(i\)

左子树的先序序列区间为 \([1,i]\),右子树的先序序列区间为 \([i+1,n-1]\)

左子树的中序遍历区间为 \([0,i-1]\),右子树的中序遍历区间为 \([i+1,n-1]\)

接着往左子树和右子树递归构建二叉树

代码

/**
1.时间复杂度:O(n)
对于每个节点都有创建过程以及根据左右子树重建过程。
2.空间复杂度:O(n)
存储整棵树的开销。
**/
class Solution
{
public:
    TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin)
    {
        // 若遍历序列为空,则说明到达叶子节点,返回NULL
        if (pre.size() == 0)
        {
            return NULL;
        }
        // 创建根节点(根节点必是前序遍历的第一个数)
        TreeNode *root = new TreeNode(pre[0]);
        // 找到中序遍历根节点所在位置i
        int i;
        for (i = 0; i < vin.size(); i++)
        {
            if (vin[i] == pre[0])
                break;
        }
        /**
        pre_left: 针对左子树的前序遍历序列
        pre_right: 针对右子树的前序遍历序列
        vin_left: 针对左子树的中序遍历序列
        vin_right: 针对右子树的中序遍历序列
        **/
        vector<int> pre_left, vin_left, pre_right, vin_right;
        // 在前序遍历序列pre中左子树区间为[1,i],右子树区间为[i+1,end]
        pre_left.assign(pre.begin() + 1, pre.begin() + i + 1);
        pre_right.assign(pre.begin() + i + 1, pre.end());
        // 在中序遍历序列vin中左子树区间为[0,i-1],右子树区间为[i+1,end]
        vin_left.assign(vin.begin(), vin.begin() + i);
        vin_right.assign(vin.begin() + i + 1, vin.end());
        // 递归求解根节点的左右子树对应的根节点
        root->left = reConstructBinaryTree(pre_left, vin_left);
        root->right = reConstructBinaryTree(pre_right, vin_right);
        // 返回根节点
        return root;
    }
};

说明

\(vector::assign\) 用法

用途

为向量分配新内容,替换其当前内容,并相应地修改其大小。

参数\(first,last\)

将迭代器输入序列中的初始位置和最终位置。使用的范围是\([first,last)\),左闭右开,包括 \(first\) 指向的元素,不包括 \(last\) 指向的元素。

Example
// vector assign
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> first;
  std::vector<int> second;
  std::vector<int> third;

  first.assign (7,100);             // 7 ints with a value of 100

  std::vector<int>::iterator it;
  it=first.begin()+1;

  second.assign (it,first.end()-1); // the 5 central values of first

  int myints[] = {1776,7,4};
  third.assign (myints,myints+3);   // assigning from array.

  std::cout << "Size of first: " << int (first.size()) << '\n';
  std::cout << "Size of second: " << int (second.size()) << '\n';
  std::cout << "Size of third: " << int (third.size()) << '\n';
  return 0;
}
Output
Size of first: 7 
Size of second: 5 
Size of third: 3 
posted @ 2020-12-04 15:45  RiverCold  阅读(46)  评论(0编辑  收藏  举报