LCP 52. 二叉搜索树染色
欢迎各位勇者来到力扣城,本次试炼主题为「二叉搜索树染色」。
每位勇士面前设有一个二叉搜索树的模型,模型的根节点为 root,树上的各个节点值均不重复。初始时,所有节点均为蓝色。现在按顺序对这棵二叉树进行若干次操作, ops[i] = [type, x, y] 表示第 i 次操作为:
type 等于 0 时,将节点值范围在 [x, y] 的节点均染蓝
type 等于 1 时,将节点值范围在 [x, y] 的节点均染红
请返回完成所有染色后,该二叉树中红色节点的数量。
注意:
题目保证对于每个操作的 x、y 值定出现在二叉搜索树节点中
示例 1:
输入:root = [1,null,2,null,3,null,4,null,5], ops = [[1,2,4],[1,1,3],[0,3,5]]
输出:2
解释:
第 0 次操作,将值为 2、3、4 的节点染红;
第 1 次操作,将值为 1、2、3 的节点染红;
第 2 次操作,将值为 3、4、5 的节点染蓝;
因此,最终值为 1、2 的节点为红色节点,返回数量 2
示例 2:
输入:root = [4,2,7,1,null,5,null,null,null,null,6]
ops = [[0,2,2],[1,1,5],[0,4,5],[1,5,7]]
输出:5
解释:
第 0 次操作,将值为 2 的节点染蓝;
第 1 次操作,将值为 1、2、4、5 的节点染红;
第 2 次操作,将值为 4、5 的节点染蓝;
第 3 次操作,将值为 5、6、7 的节点染红;
因此,最终值为 1、2、5、6、7 的节点为红色节点,返回数量 5
代码题解如下,其实这一题采用逆向思维,逆向进行检索,将会非常简单
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct Node{
int left;
int right;
struct Node *next;
};
void dfs(struct TreeNode* root,int *a,int *p){
if(root){
dfs(root->left,a,p);
a[*p]=root->val;
(*p)++;
dfs(root->right,a,p);
}
}
void insert(struct Node* o,int left,int right){
struct Node* p=o->next;
while(p){
if(left>=p->left&&right<=p->right){
break;
}
if(right<=p->right&&right>=p->left-1&&left<=p->left-1){
p->left=left;
break;
}
if(left>=p->left&&left<=p->right+1&&right>=p->right+1){
p->right=right;
break;
}
p=p->next;
}
if(p==NULL){
struct Node *s=(struct Node*)malloc(sizeof(struct Node));
s->left=left;
s->right=right;
s->next=o->next;
o->next=s;
}
}
void delete(struct Node* o,int left,int right){
struct Node* p=o->next;
struct Node* pre=o;
while(p){
printf("p %d %d ",p->left,p->right);
if(left<=p->left&&right>=p->right){
pre->next=p->next;
}
if(left<=p->left&&right<p->right&&right>=p->left){
p->left=right+1;
}
if(left>p->left&&left<=p->right&&right>=p->right){
p->right=left-1;
}
if(left>p->left&&right<p->right){
struct Node *s=(struct Node*)malloc(sizeof(struct Node));
s->left=right+1;
s->right=p->right;
p->right=left-1;
s->next=p->next;
p->next=s;
}
pre=p;
p=p->next;
}
}
int B_find(int *a,int val,int low,int high){
if(low==high){
return low;
}
int mid=(low+high)/2;
if(a[mid]>val){
return B_find(a,val,low,mid-1);
}
if(a[mid]<val){
return B_find(a,val,mid+1,high);
}
return mid;
}
int getNumber(struct TreeNode* root, int** ops, int opsSize, int* opsColSize){
int *a=(int *)malloc(sizeof(int)*5000);
int *p=(int *)malloc(sizeof(int));
int *op=(int *)malloc(sizeof(int)*5000);
int i;
struct Node *o=(struct Node*)malloc(sizeof(struct Node));
o->next=NULL;
struct Node *s;
*p=0;
dfs(root,a,p);
for(i=0;i<opsSize;i++){
printf("|");
if(ops[i][0]==1){
insert(o,ops[i][1],ops[i][2]);
}
else{
delete(o,ops[i][1],ops[i][2]);
}
}
s=o->next;
int sum=0;
while(s){
printf("|| %d %d ",s->left,s->right);
int left_index=B_find(a,s->left,0,*p-1);
printf("le %d ",a[left_index]);
if(a[left_index]<s->left){
left_index++;
}
int right_index=B_find(a,s->right,0,*p-1);
// printf("ri %d ",a[right_index]);
sum=right_index-left_index+sum+1;
s=s->next;
}
return sum;
}