二叉搜索树 |
---|
题意: 给定一棵二叉搜索树的序列,判断其他的序列是否和这个序列构造成相同的二叉搜索树。
题解: 前不久刚学到一篇不错建树方法,所以仿造了类似的思路,将给定的序列按照后序遍历建树(前序也可,中序貌似不行)——实际上就是按照后续遍历将所有节点存放在数组中。如果将所有的序列按照后续遍历建树的话,那么只有数组中元素相同的序列才可能构造成相同的二叉搜索树。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int n;
char s[22][11];
vector<int> ans[22];
void build(int id, vector<int> tree) {
if(tree.size() == 0) return ; //树中已无元素,退出
vector<int> left, right;
for(int i = 1; i < tree.size(); i++) {
if(tree[i] > tree[0]) right.push_back(tree[i]); //将所有大于根节点的节点放进右子树
else left.push_back(tree[i]); //将所有小于等于根节点的节点放进左子树
}
build(id, left); //针对左子树进行建树
build(id, right); //针对右子树进行建树
ans[id].push_back(tree[0]); //后序遍历
}
void run(int id) {
vector<int> tree;
int len = strlen(s[id]);
for(int i = 0; i < len; i++) //取出所有节点
tree.push_back(s[id][i] - '0');
build(id, tree); //建树
}
int main() {
while(~scanf("%d", &n) && n) {
for(int i = 0; i < 22; i++) ans[i].clear();
scanf("%s", s[0]);
int length = strlen(s[0]);
run(0); //事先处理比较的母序列
for(int i = 1; i <= n; i++) {
scanf("%s", s[i]);
int len = strlen(s[i]);
if(len = length) { //比较两个序列的长度
run(i);
int flag = 1;
for(int j = 0; j < len && flag; j++)
if(ans[0][j] != ans[i][j]) flag = 0;
if(flag) printf("YES\n");
else printf("NO\n");
} else
printf("NO\n");//虽然不确定题目中是否有卡这个点
//但是逻辑上元素个数都不相同的序列一定不能构造成相同的二叉搜索树
}
}
return 0;
}