https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456
思路:二叉树的后序遍历和中序遍历可以确定这颗二叉树的形状(左右根、左根右,找到根节点然后分出左右子树递归处理),那么最普通的思路就是据此建立出一颗二叉搜索树,那么再对其做层次遍历。但是这样写太麻烦了,我们考虑最开始所提到的递归过程,显然同一层的节点将按照从左至右的顺序被访问(不一定连续被访问哦),但是同一层有序已经满足我们的需求了,只不过最后需要按照深度把他们串起来,所以我们引入一个
d
e
e
p
deep
deep二维数组,在递归中暂存每一层的值即可。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
using ll=long long;
vector<int> deep[35];
vector<int> inOrder,postOrder;
void dfs(int l1,int r1,int l2,int r2,int dep)
{
if(l1>r1)
return ;
int root=postOrder[r1];//后序 左右根
int rootIdx=l2;
while(rootIdx<=r2&&inOrder[rootIdx]!=root)
++rootIdx;
deep[dep].push_back(root);
int rchildNum=r2-rootIdx;
dfs(l1,r1-rchildNum-1,l2,rootIdx-1,dep+1);
dfs(r1-rchildNum,r1-1,rootIdx+1,r2,dep+1);
}
int main()
{
int n;
scanf("%d",&n);
inOrder.resize(n),postOrder.resize(n);
for(int i=0;i<n;i++)
scanf("%d",&postOrder[i]);
for(int i=0;i<n;i++)
scanf("%d",&inOrder[i]);
dfs(0,n-1,0,n-1,0);
printf("%d",deep[0][0]);
for(int i=1;i<n;i++)
{
if(!deep[i].size())
break;
for(int v:deep[i])
printf(" %d",v);
}
printf("\n");
return 0;
}