【每日一题Day335】LC1993树上的操作 | dfs

简介: 【每日一题Day335】LC1993树上的操作 | dfs

树上的操作【LC1993】

给你一棵 n 个节点的树,编号从 0n - 1 ,以父节点数组 parent 的形式给出,其中 parent[i] 是第 i 个节点的父节点。树的根节点为 0 号节点,所以 parent[0] = -1

因为它没有父节点。你想要设计一个数据结构实现树里面对节点的加锁,解锁和升级操作。

数据结构需要支持如下函数:

  • **Lock:**指定用户给指定节点 上锁 ,上锁后其他用户将无法给同一节点上锁。只有当节点处于未上锁的状态下,才能进行上锁操作。
  • **Unlock:**指定用户给指定节点 解锁 ,只有当指定节点当前正被指定用户锁住时,才能执行该解锁操作。
  • Upgrade:

指定用户给指定节点

上锁

,并且将该节点的所有子孙节点

解锁

。只有如下 3 个条件

全部

Upgrade:

指定用户给指定节点

上锁

,并且将该节点的所有子孙节点

解锁

。只有如下 3 个条件

全部

请你实现 LockingTree 类:


LockingTree(int[] parent) 用父节点数组初始化数据结构。

lock(int num, int user) 如果 id 为 user 的用户可以给节点 num 上锁,那么返回 true ,否则返回 false 。如果可以执行此操作,节点 num 会被 id 为 user 的用户 上锁 。

  • unlock(int num, int user) 如果 id 为 user 的用户可以给节点 num 解锁,那么返回 true ,否则返回 false 。如果可以执行此操作,节点 num 变为 未上锁 状态。
  • upgrade(int num, int user) 如果 id 为 user 的用户可以给节点 num 升级,那么返回 true ,否则返回 false 。如果可以执行此操作,节点 num 会被 升级


  • 思路使用数组记录每个节点的父节点以及上锁状态,并使用list记录每个节点的孩子节点,方便dfs操作
  • lock和unlock函数进行简单判断即可
  • upgrade函数需要判断祖先节点是否上锁,再通过dfs判断是否有上锁的孩子节点,并将其解锁
  • 实现
class LockingTree {
    // 记录每个节点的根节点以及加锁状态
    int[] locked;
    int[] parent;
    int n;
    List<Integer>[] children;
    public LockingTree(int[] parent) {
        this.n = parent.length;
        this.parent = parent;
        this.locked = new int[n];
        this.children = new List[n];
        Arrays.fill(locked, -1);
        Arrays.setAll(children, e -> new ArrayList<>());
        for (int i = 0; i < n; i++){
            if (parent[i] != -1){
                children[parent[i]].add(i);
            }
        }
    }
    public boolean lock(int num, int user) {
        if (locked[num] != -1) return false;
        locked[num] = user;
        return true;
    }
    public boolean unlock(int num, int user) {
        if (locked[num] == user){
            locked[num] = -1;
            return true;
        }
        return false;
    }
    public boolean upgrade(int num, int user) {
        if (locked[num] != -1) return false;
        // 判断祖先节点是否上锁
        int p = parent[num];
        while (p != -1){
            if (locked[p] != -1) return false;
            p = parent[p];
        }
        // 判断是否有子孙节点加锁了,并给子孙节点解锁
        boolean[] res = {false};
        dfs(num, res);
        if (res[0] == false) return false;
        locked[num] = user;
        return true;
    }
    public void dfs(int p, boolean[] lock){
        for (int u : children[p]){
            if (locked[u] != -1){
                lock[0] = true;
                locked[u] = -1;               
            }
            dfs(u, lock);
        }
    }
}
/**
 * Your LockingTree object will be instantiated and called as such:
 * LockingTree obj = new LockingTree(parent);
 * boolean param_1 = obj.lock(num,user);
 * boolean param_2 = obj.unlock(num,user);
 * boolean param_3 = obj.upgrade(num,user);
 */

image.png

目录
相关文章
|
存储 弹性计算 NoSQL
libcuckoo论文概述
本文简要阐述libcuckoo项目的两篇论文基础。如有错漏之处,欢迎指出一起讨论交流。 ## 论文1 《MemC3: Compact and Concurrent MemCache with Dumber Caching and Smarter Hashing》 这篇论文主要讲了在多线程模式下如何提升cuckoo hash table的吞吐。 ### 问题 传统hash表在并发效率上并不
2044 0
libcuckoo论文概述
|
存储 运维 安全
无影云应用重磅发布
本文整理自阿里云无影高级产品专家褚晓璐,在阿里云EMR StarRocks无影云应用线上发布会的分享。本篇内容主要分为三个部分: 1.无影云应用架构概览 2.无影云的应用场景 3.畅想未来
1237 0
无影云应用重磅发布
|
11月前
|
JSON API 数据安全/隐私保护
拍立淘按图搜索API接口返回数据的JSON格式示例
拍立淘按图搜索API接口允许用户通过上传图片来搜索相似的商品,该接口返回的通常是一个JSON格式的响应,其中包含了与上传图片相似的商品信息。以下是一个基于淘宝平台的拍立淘按图搜索API接口返回数据的JSON格式示例,同时提供对其关键字段的解释
|
缓存 Java 测试技术
Spring Boot中的性能测试与调优
Spring Boot中的性能测试与调优
|
缓存 Java
线程的四种创建方式
线程的四种创建方式
|
XML SQL 设计模式
Spring——什么是事务?传播行为?事务隔离级别有哪些?
提交事务(如果核心业务处理过程中没有出现异常)(commit transaction)
|
Cloud Native 大数据
阿里云最新产品手册——阿里云核心产品——云原生大数据计算服务——智能物流
阿里云最新产品手册——阿里云核心产品——云原生大数据计算服务——智能物流自制脑图
195 1
|
机器学习/深度学习 数据采集 人工智能
ICASSP 2022 | 89.46%检出率,网易云信音频实验室提出全球首个AI啸叫检测方案(2)
ICASSP 2022 | 89.46%检出率,网易云信音频实验室提出全球首个AI啸叫检测方案
428 0
|
网络安全 Apache
《笑小枫》工具篇之HttpClient详解
《笑小枫》工具篇之HttpClient详解
324 0
|
新零售 大数据 云计算
二二复制公排开发功能丨二二复制公排系统开发(开发原理)丨二二复制公排源码详细
 新零售的另一个新层次是互联网+技术(大数据、云计算、移动支付等)它可以连接线上和线下,实现全面覆盖,并通过技术提高零售能力。使企业能够更清晰地获得消费者的形象,同时刺激消费者的消费,创造更好的消费者体验。