题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
使用语言:C++(clang++3.9)
时间限制:< 1s
空间限制:< 32M
解题思路:
题目考查重点应该是二叉树的遍历和特性.二叉数有三种遍历方式.
1.先序遍历:根->左->右;
2.中序遍历:左->根->右;
3.后序遍历:左->右->根.
按照遍历特性,先序遍历的第一个数值就是本层树根节点的值,同时,这个值将中序遍历的数组值分成左右子树.这样一来,本层树结构就出来了.按照这个方式,逐步递归到树叶,政客树就建立起来了.
#include <stack>
#include <stdio.h>
#include <vector>
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x)
: val(x)
, left(NULL)
, right(NULL)
{
}
};
class Solution {
public:
TreeNode* reConstructBinaryTree(std::vector<int> pre, std::vector<int> vin)
{
int inlen = vin.size();
if (inlen == 0) {
return NULL;
}
std::vector<int> left_pre, left_in, right_pre, right_in;
// 先序遍历的首个值就是根节点值.
TreeNode* NodeHead = new TreeNode(pre[0]);
//寻找先需遍历头节点在中序遍历的位置,位置的左边是左子树,右边是右子树;
int index = 0;
for (; index < inlen; index++) {
if (vin[index] == pre[0]) {
break;
}
}
//根据先序遍历和中序遍历的特性,先序遍历的值将中序遍历分为左右子树,而且根节点之后的连续数值都是左子树的值.
for (int i = 0; i < index; i++) {
//左子树的先序遍历, 去掉上一层的根节点
left_pre.push_back(pre[i + 1]);
//左子树的中序遍历,
left_in.push_back(vin[i]);
}
for (int i = index + 1; i < inlen; i++) {
//右子树的先序遍历, 去掉上一层的根节点
right_pre.push_back(pre[i]);
//右子树的中序遍历,
right_in.push_back(vin[i]);
}
//以上的操作会得出一层的左右子树和根节点情况,要取到树叶,需要进行迭代,
NodeHead->left = reConstructBinaryTree(left_pre, left_in);
NodeHead->right = reConstructBinaryTree(right_pre, right_in);
return NodeHead;
};
};
实验结果:
运行时间:6ms 占用内存:664k