版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014046022/article/details/81673449
描述
有一棵包含N个节点的二叉树,节点编号是1~N。
现在我们知道它的中序遍历结果A1, A2, … AN。
只有中序遍历显然不能确定一棵二叉树的形态,可能有很多棵不同的二叉树符合给定的中序遍历。
那么你能从中找出先序遍历结果字典序最小的二叉树吗?
设先序遍历结果是P1, P2, … PN。字典序最小指首先P1应尽量小,其次P2尽量小,再次P3尽量小…… 以此类推。
输入
第一行包含一个整数N。 (1 <= N <= 100)
以下N行每行包含一个整数Ai。 (1 <= Ai <= N)
输出
输出N行,依次是P1, P2, … PN。代表最小的先序遍历结果。
样例输入
5
5
4
1
3
2
样例输出
1
4
5
2
3
思路:
由于只知道中序序列,中序序列相同的树有很多,显然不能暴力枚举。这时候想想先序和中序的关系,先序字典序最小,先序遍历先遍历根节点,也就是根节点要最小。所以我们可以找到中序序列中的最小值,将它作为树的根节点,将中序序列分为两部分,然后递归的对这两部分按照同样的策略找根。这样构造的先序序列保证是字典序最小的。
#include <bits/stdc++.h>
using namespace std;
vector<int>A;
vector<int>res;
void solve(int l,int r)
{
if (l > r) return;
if (l == r) {
res.push_back(A[l]);
return;
}
int mid = l;
for (int i = l; i <= r; ++i) {
if (A[i] <= A[mid]) {
mid = i;
}
}
res.push_back(A[mid]);
solve(l,mid-1);
solve(mid+1,r);
}
int main()
{
int n,x;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> x;
A.push_back(x);
}
solve(0,n-1);
for (auto x: res) {
cout << x << endl;
}
return 0;
}