【PAT】1119. Pre- and Post-order Traversals (30)【二叉树的遍历】

题目描述

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

翻译:假设二叉树中的所有键都是不同的正整数。一棵唯一的二叉树可以由给定的一对后序和中序遍历序列或先序和中序遍历序列确定。但是,如果只给出后序和前序遍历序列,相应的树可能不再是唯一的。
现在给定一对后序和先序遍历序列,您应该输出树的相应的中序遍历序列。如果树不是唯一的,只需输出其中任何一个。

Input Specification:

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

翻译:每个输入文件包含一组测试数据。对于每组测试数据,第一行给定一个正整数N (≤ 30), 表示二叉树中的总结点数。第二行给出先序遍历数列并且第三行给出后序遍历数列。一行内所有数字之间用空格隔开。

Output Specification:

For each test case, first printf in a line Yes if the tree is unique, or No if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

翻译:对于每组输入数据,如果树唯一输出一行Yes,否则输出No。接着在第二行输出相应的二叉树的中序遍历数列。如果结果不唯一,任何结果都可以。数据保证至少存在一个结果。一行内所有数字之间必须用空格隔开,并且行末尾不能有多余空格。


Sample Input 1:

7
1 2 3 4 6 7 5
2 6 7 4 5 3 1


Sample Output 1:

Yes
2 1 6 4 7 3 5


Sample Input 2:

4
1 2 3 4
2 4 3 1


Sample Output 2:

No
2 1 3 4


解题思路

这道题的主要考点是对树的左右子树进行递归划分,每次先去掉当前根节点,然后将先序数列和后序数列分别划分成左右两段。左右标记重合时就将其压入栈。判断划分出来的两个区域即左右子树均存在,如果有一方不存在则说明树不唯一。详细见代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<algorithm>
#define INF 99999999
#define bug puts("Hello\n")
using namespace std;
vector<int> in;
bool Unique = true;
int N,pre[35],post[35];
void fun(int preL,int preR,int postL,int postR){
	if(preL==preR){
		in.push_back(pre[preL]); 
		return ;
	}
	if(pre[preL]==post[postR]){
		int i=0;
    	while(post[postL+i]!=pre[preL+1])i++;
    	if(i==0&&preL+i+2>preR)Unique=false;
    	fun(preL+1,preL+1+i,postL,postL+i);
    	in.push_back(pre[preL]);
    	if(preL+i+2<=preR)
    	fun(preL+i+2,preR,postL+i+1,postR-1);
	}
}
int main() {
    scanf("%d", &N);
    for(int i=0;i<N;i++) scanf("%d", &pre[i]);
    for (int i=0;i<N;i++) scanf("%d", &post[i]);
    fun(0,N-1,0,N-1);
    if(Unique==true)printf("Yes\n");
	else printf("No\n");
    for (int i = 0; i < in.size()-1; i++)
        printf("%d ", in[i]);
    printf("%d\n",in[N-1]);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值