思路:
1.根据先根遍历序列和二叉寻找树这两个性质构造一颗二叉树:以所给值的绝对值为key,同时以key值为键用map存储颜色;
2.判断根结点颜色;
3.在构造二叉树时判断,若结点为红色,孩子结点有没有为红色的;
4.遍历二叉树,递归计算以每个结点为根节点的树的所有路径黑色结点个数(注意是每个结点,不只是整棵树的根节点);
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
unordered_map<int,int> mp;
vector<int> v;
unordered_map<int,pair<int,int>> node;
bool isRB=true;
void buildTree(int beg,int end){
int right,left=beg+1;
for(right=beg+1;right<=end&&v[right]<v[beg];right++);
if(v[left]<v[beg]&&left<=right-1){
node[v[beg]].first=v[left];
if(left<right-1) buildTree(left,right-1);
}
if(right<=end){
node[v[beg]].second=v[right];
if(right<end) buildTree(right,end);
}
if(mp[v[beg]]<0) isRB=mp[node[v[beg]].first]<0||mp[node[v[beg]].second]<0?false:isRB;
}
int testBlack(int root){
int nleft=0,nright=0;
if(node[root].first!=0&&isRB) nleft=testBlack(node[root].first);
if(node[root].second!=0&&isRB) nright=testBlack(node[root].second);
if(nleft!=nright) isRB=false;
return nleft+nright+mp[root]>0?1:0;
}
int main(){
int k,n,no;
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&n);
for(int j=0;j<n;j++){
scanf("%d",&no);
v.push_back(abs(no));
mp[abs(no)]=no>0?1:-1;
}
buildTree(0,n-1);
if(mp[v[0]]<0||!isRB) printf("No
");
else{
testBlack(v[0]);
printf(isRB==true?"Yes
":"No
");
}
mp.clear(); v.clear(); node.clear(); isRB=true;
}
return 0;
}