该题为判断一串整数序列是否为一棵二叉搜索树或镜像二叉搜索树的前序输出序列
#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int a[N];
int s[N];
int n, idx;
void pre(int l, int r, bool flag)
// flag判断此函数按照何种方式进行二叉搜索树判断
// 若flag为false,则按照bst区分左右子树,若为true,则按照镜像bst区分左右子树
{
if (l > r)
return;
int lc = r, rc = l + 1;
if (!flag) // 若按照bst
{
while (lc > l && a[lc] >= a[l]) // 从有到左找左子树右边界,一直找到第一个小于根值的数的位置
lc--;
while (rc <= r && a[rc] < a[l]) // 从左到右找右子树左边界,一直找到第一个大于根值的数的位置
rc++;
}
else // 镜像bst同理
{
while (lc > l && a[lc] < a[l])
lc--;
while (rc <= r && a[rc] >= a[l])
rc++;
}
if (lc != rc - 1) // 若找到的左子树有边界不在右子树左边界左边
// 则说明该序列不为bst或镜像bst的前序输出序列
return;
pre(l + 1, lc, flag); // 递归判断左子树
pre(rc, r, flag); // 递归判断右子树
s[idx++] = a[l]; // 在全部递归结束后将根值存入数组,则为后序输出序列
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
pre(0, n - 1, false); // 先按照bst判断
if (idx != n) // 若数组中的元素个数不为n则说明判断失败
{
idx = 0;
pre(0, n - 1, true); // 再按照镜像bst判断
}
if (idx != n) // 若仍判断失败则不为bst或镜像bst
cout << "NO";
else
{
cout << "YES" << endl;
for (int i = 0; i < idx; i++)
{
if (i == idx - 1)
cout << s[i];
else
cout << s[i] << " ";
}
return 0;
}
}