PAT甲级1138 Postorder Traversal (25分) 前序 中序 转换后序

1138 Postorder Traversal (25分)
Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and inorder traversal sequences, you are supposed to output the first number of the postorder traversal sequence of the corresponding binary tree.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 50,000), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print in one line the first number of the postorder traversal sequence of the corresponding binary tree.

Sample Input:
7
1 2 3 4 5 6 7
2 3 1 5 4 7 6
Sample Output:
3

常规题,前序 中序 转换为后序,但这个可以偷下懒,因为人家只要求输出 对应二叉树 后序遍历的第一个元素,那么我们就在深搜分析二叉树的时候对瞄准了这个后序遍历第一个元素来就好了。 比如拿样例来分析下

  1. 我们 前序 后序深搜时候,1 2 3 4 5 6 7 ,2 3 1 5 4 7 6两个数列,先分析出来了根节点为1
  2. 根据1在中序里面的位置,可知左子树的中序 为2 3,右子树的中序为 5 4 7 6
  3. 然后因为我们只要求后序遍历的第一个元素,那么在左右子树都存在的情况只关注左子树,只存在右子树则只关注右子树,即 前序 2 3,中序也是2 3。
  4. 然后和开头一样,先分析出根节点为2,左子树为空,右子树为3,那么在仅仅右子树存在的情况只关注右子树,所以这个3就是我们所求的后序遍历的第一个元素。

实现代码如下:

#include <iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

int sn1[50001];
int sn2[50001];

int  df(int N,int sn1S,int sn2S){
    //sn1 是前序 sn2是中序
    int root=sn1[sn1S];
    int rootPos=sn2S;
    while(sn2[rootPos]!=root)
        rootPos++;
    //左子树的个数是 rootPos-rightS
    int leftNumber=rootPos-sn2S;
    int rightNumber=N-1-leftNumber;
    //题目就是求后序遍历的第一个元素,那么同时有左右子树,遍历左子树 没有左子树了才遍历右子树
    if(leftNumber>1){// 左子树有两个及两个以上的元素,还需要递归分析左子树
        df(leftNumber,sn1S+1,sn2S);
    }
    else if(leftNumber==1){//左子树只有一个元素就是我们所求的元素了
        return sn2[sn2S];
    }
    else if(rightNumber>1){
        df(rightNumber,sn1S+1,rootPos+1);
    }
    else if(rightNumber==1){
         return sn2[rootPos+1];
    }
    else
        return -1;
}
int main()
{
    int N;
    cin>>N;
    for(int i=0; i<N; i++)
    {
        cin>>sn1[i];
    }
    for(int i=0; i<N; i++)
    {
        cin>>sn2[i];
    }
   cout<<df(N,0,0);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值