题目链接:​​http://acm.hdu.edu.cn/showproblem.php?pid=3791​

题目大意:

给你 \(n+1\) 棵二叉搜索树的插入序列。
问后 \(n\) 个序列对应的二叉搜索树和第 \(1\) 个序列对应的二叉搜索树是不是同一个。

解题思路:

首先,模拟二叉搜索树的插入形成一棵树。

然后判断两棵树是不是相同。

这里我茅塞顿开发现使用树的 先序遍历 可以判断两棵二叉搜索树是否相同。

因为二叉搜索树的特性能够保证左子树中的元素都比根节点小,右子树中的元素都比根节点大。
所以我们能保证先序遍历能够确定根节点+左子树+右子树,所以能够还原出整棵树。神奇!

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 22;
char s[maxn], val[maxn];
int n, len, id, lson[maxn], rson[maxn];
string tmp;
void init() {
id = 0;
memset(lson, 0, sizeof(lson));
memset(rson, 0, sizeof(rson));
}
void ins(char c) {
val[++id] = c;
if (id == 1) return;
int x = 1;
while (true) {
if (c < val[x]) {
if (!lson[x]) {
lson[x] = id;
return;
}
else x = lson[x];
}
else {
if (!rson[x]) {
rson[x] = id;
return;
}
else x = rson[x];
}
}
}
void handle(int x) {
tmp += val[x];
if (lson[x]) handle(lson[x]);
if (rson[x]) handle(rson[x]);
}
string transfer() {
len = strlen(s);
init();
for (int i = 0; i < len; i ++) ins(s[i]);
tmp = "";
handle(1);
return tmp;
}
int main() {
while (~scanf("%d", &n) && n) {
scanf("%s", s);
string res1 = transfer();
while (n --) {
scanf("%s", s);
string res2 = transfer();
puts(res1 == res2 ? "YES" : "NO");
}
}
return 0;
}