题目大意:给出二叉树的前序和中序序列(<=50000节点),输出后序遍历输出的第一个节点。
由于节点数量过多,如果先建树后遍历的话会超时。因此要考虑后序遍历的特点,后序遍历输出的第一个节点是在先序遍历过程中遇到的第一个叶子节点,也就是在建树过程中第一个左右孩子都为空的节点。因此,在建树过程中遇到左右孩子为空的节点,就可以直接结束建树过程,输出这个值。为了避免超时,用map存储中序序列的值和对应下标,不需要再遍历中序序列获得元素的下标。
AC代码:
#include <iostream>
#include <vector>
#include <cstdio>
#include <map>
using namespace std;
vector<int> pre;
map<int, int> in;
struct Node
{
int data;
Node* left;
Node* right;
Node(int data):data(data), left(NULL), right(NULL){};
};
void createFromPreIn(Node* &node, int prel, int prer, int inl, int inr, bool &flag, int &ret)
{
if(prel > prer || flag) return;
if(node == NULL) node = new Node(pre[prel]);
int index = in[pre[prel]];
int leftNum = index - inl;
int rightNum = inr - index;
if(leftNum == 0 && rightNum == 0)
{
flag = true;
ret = pre[prel];
return;
}
createFromPreIn(node->left, prel + 1, prel + leftNum, inl, index - 1, flag, ret);
createFromPreIn(node->right, prel + leftNum + 1, prer, index + 1, inr, flag, ret);
}
int main()
{
int N;
scanf("%d", &N);
pre.resize(N);
for (int i = 0; i < N; ++i)
{
scanf("%d", &pre[i]);
}
for (int i = 0; i < N; ++i)
{
int data;
scanf("%d", &data);
in[data] = i;
}
Node* root = NULL;
bool flag = false;
int ret = 0;
createFromPreIn(root, 0, N-1, 0, N-1, flag, ret);
printf("%d", ret);
return 0;
}