LCP 52. 二叉搜索树染色-先序遍历加二分查找

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;







}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值