L2-004これは二分探索木ですか?(25点)
二分探索木は、次のプロパティを持つ二分木として再帰的に定義できます。任意のノードの場合、
- 左側のサブツリー内のすべてのノードのキー値は、ノードのキー値よりも小さくなっています。
- 右側のサブツリー内のすべてのノードのキー値は、ノードのキー値以上です。
- 左右のサブツリーは二分探索木です。
二分探索木のいわゆる「ミラー」は、すべてのノードの左右のサブツリーの位置を交換した後に取得されるツリーです。
整数キー値のシーケンスが与えられた場合、これが二分探索木またはその鏡像を事前にトラバースした結果であるかどうかを判断するプログラムを作成してください。
入力フォーマット:
入力の最初の行は正の整数N(≤1000)を与えます。次の行は、スペースで区切られたN個の整数キー値を示しています。
出力フォーマット:
入力シーケンスが二分探索木またはそのミラーのプレオーダートラバーサルの結果である場合、最初に1行にYESを出力し、次に次の行にツリーの後続のトラバーサルの結果を出力します。数字の間に1つのスペースがあり、行の最初と最後に余分なスペースがあってはなりません。答えが「いいえ」の場合は、「いいえ」を出力します。
入力例1:
7
8 6 5 7 10 8 11
出力サンプル1:
YES
5 7 6 8 11 10 8
入力例2:
7
8 10 11 8 6 7 5
出力サンプル2:
YES
11 8 10 7 5 6 8
入力サンプル3:
7
8 6 8 5 10 9 11
出力サンプル3:
NO
問題解決
二分木のトラバーサルは、シーケンスを2つのサブツリーに分割する分割点を見つけて、dfsで検索する
ことです。この問題は、ルートノードがすべての左側のサブツリーよりも大きく、より小さいことを特徴とする二分探索木です。またはすべての右サブツリーに等しい。これは、カットオフポイントを見つけて
、dfs検索を一覧表示するための条件です。
コード
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int maxn = 1e3 + 2;
vector<int> v, v_back;
bool isTree = true;
void dfs(int root, int l, int r) {
// Õý³£ËÑË÷Ê÷
if(l > r) return;
int k = root;
for(int i = l + 1; i <= r; i++)
if(v[i] < v[root]) k = i;
else break;
for(int i = k + 1; i <= r; i++)
if(v[i] < v[root]) {
isTree = false;
break;
}
dfs(root + 1, root + 1, k);
dfs(k + 1, k + 1, r);
v_back.push_back(v[root]); //»ñÈ¡ºóÐò±éÀú
}
void dfs_back(int root, int l, int r) {
//ËÑË÷Ê÷¾µÏñ
if(l > r) return;
int k = root;
for(int i = l + 1; i <= r; i++)
if(v[i] >= v[root]) k = i;
else break;
for(int i = k + 1; i <= r; i++)
if(v[i] >= v[root]) {
isTree = false;
break;
}
dfs_back(root + 1, root + 1, k);
dfs_back(k + 1, k + 1, r);
v_back.push_back(v[root]);
}
int main() {
int N;
cin >> N;
v.resize(N);
for(int i = 0; i < N; i++) cin >> v[i];
if(N == 1) {
//ÌØÅÐ
cout << "YES" << endl;
cout << v[0] << endl;
return 0;
}
if(v[1] < v[0])
dfs(0, 0, v.size() - 1);
else
dfs_back(0, 0, v.size() - 1);
if(isTree) {
cout << "YES" << endl;
for(int i = 0; i < v_back.size(); i++) {
if(i) cout << " ";
cout << v_back[i];
}
} else
cout << "NO" << endl;
return 0;
}