1138 Postorder Traversal

传送门

看别人的题解基本都是递归建树,然后找最下的点,但是我这个方法应该会快很多,

因为中序遍历的特性,从左向右的数再树中的位置都是一个没有左子树的节点

可以循环查找,假如有如下树

 

1138 Postorder Traversal

中序遍历:2 4 6 7 5 3  1

先序遍历 1 2 3 4 5 6 7 

首先找到中序遍历的前两个数,2,4,在前序遍历的位置分别为pos1(1),pos2(3),显然pos1<pos2,即前序遍历中2比4先遍历到,然后位置向后移动,找到中序遍历的第二个数和第三个数在前序遍历中的位置,

即4 6,只需此时的pos1仍然小于pos2,继续移动,即6 7,此时pos1仍然小于pos2,继续移动,即7 5,此时pos1>pos2循环结束,pos1位置的元素7即为后序遍历第一个元素,QAQ,是不是很简单,很快速

程序中用一个map定位元素在先序遍历中的位置,如果你之前用过他来定位中序遍历位置建树,你应该不陌生,然后还要注意n==1,就直接输出那个点就行了.

代码:

#include<iostream>
#include<queue>
#include<string.h>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
const int maxn = 5e4 + 1;
const int maxm = 1e6 + 1;
#define INT_MAX 0x7777777
typedef long long ll;
inline int read()
{
    int X = 0; bool flag = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-') flag = 0; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { X = (X << 1) + (X << 3) + ch - '0'; ch = getchar(); }
    if (flag) return X;
    return ~(X - 1);
}
int n;
vector<int>pre, ino;
map<int, int>M;
int main() {
    n = read();
    pre.resize(n);
    ino.resize(n);
    for (int i = 0; i < n; i++) {
        pre[i] = read();
        M[pre[i]] = i;
    }
    for (int i = 0; i < n; i++) {
        ino[i] = read();
    }
    if (n == 1){
        printf("%d\n", pre[0]); return 0;
    }
    int i=0;
    int pos1 = M[ino[i]], pos2 = M[ino[i+1]];
    while(pos1<pos2){
      i+=1;
      pos1=pos2;
      pos2=M[ino[i+1]];
    }
    printf("%d\n",ino[i]);
    return 0;
}

 

上一篇:【java】剑指offer33_二叉搜索树的后序遍历序列


下一篇:February——剑指 Offer 33. 二叉搜索树的后序遍历序列