题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784
题意:给定二叉树的结点个数n,其前序遍历结果pre,中序遍历结果in,求其镜像二叉树的层序遍历结果。
思路:与pta l2-6基本一模一样,只不过是加了一个镜像,其实是一个意思,那道题见我另一篇博客:https://www.cnblogs.com/FrankChen831X/p/10542561.html。再来说说这道题,给二叉树每个结点一个编号,按照层序遍历的顺序依次编号,即一个编号为i的结点其左子树根节点编号为2*i+1,其右子树根节点的编号为2*i+2(二叉树的根节点为0),因为30层的二叉树编号达到了2*30-1,不能直接用数组存,会爆空间。我们可以用优先队列和二元组pair来存,pair的first存结点编号,second存该结点的值。之后就暴力递归了,与那道题不同的是这道题要求镜像之后的层序遍历结果,我们稍微换个角度来思考,只要将原来二叉树的右结点编号为2*i+1,左结点编号为2*i+2,其它的也递归进行,这样求得的层序遍历结果就是所求结果了。
AC代码:
#include<bits/stdc++.h> using namespace std; int n,pre[35],in[35]; typedef pair<int,int> PII; priority_queue<PII,vector<PII>,greater<PII> > pq; void getc(int l,int r,int root,int index){ if(l>r) return; int i=l; while(in[i]!=pre[root]) ++i; pq.push(make_pair(index,pre[root])); getc(l,i-1,root+1,index*2+2); getc(i+1,r,root+i-l+1,index*2+1); } int main(){ scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d",&in[i]); for(int i=0;i<n;++i) scanf("%d",&pre[i]); getc(0,n-1,0,0); PII p=pq.top(); pq.pop(); printf("%d",p.second); while(!pq.empty()){ p=pq.top(); pq.pop(); printf(" %d",p.second); } printf(" "); return 0; }