LeetCode每日一题:1993. 树上的操作(2023.9.23 C++)

目录

1993. 树上的操作

题目描述:

实现代码与解析:

模拟 + dfs

原理思路:


1993. 树上的操作

题目描述:

        给你一棵 n 个节点的树,编号从 0 到 n - 1 ,以父节点数组 parent 的形式给出,其中 parent[i] 是第 i 个节点的父节点。树的根节点为 0 号节点,所以 parent[0] = -1 ,因为它没有父节点。你想要设计一个数据结构实现树里面对节点的加锁,解锁和升级操作。

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

  • Lock:指定用户给指定节点 上锁 ,上锁后其他用户将无法给同一节点上锁。只有当节点处于未上锁的状态下,才能进行上锁操作。
  • Unlock:指定用户给指定节点 解锁 ,只有当指定节点当前正被指定用户锁住时,才能执行该解锁操作。
  • 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 会被 升级 

示例 1:

输入:
["LockingTree", "lock", "unlock", "unlock", "lock", "upgrade", "lock"]
[[[-1, 0, 0, 1, 1, 2, 2]], [2, 2], [2, 3], [2, 2], [4, 5], [0, 1], [0, 1]]
输出:
[null, true, false, true, true, true, false]解释:
LockingTree lockingTree = new LockingTree([-1, 0, 0, 1, 1, 2, 2]);
lockingTree.lock(2, 2);    // 返回 true ,因为节点 2 未上锁。// 节点 2 被用户 2 上锁。
lockingTree.unlock(2, 3);  // 返回 false ,因为用户 3 无法解锁被用户 2 上锁的节点。
lockingTree.unlock(2, 2);  // 返回 true ,因为节点 2 之前被用户 2 上锁。// 节点 2 现在变为未上锁状态。
lockingTree.lock(4, 5);    // 返回 true ,因为节点 4 未上锁。// 节点 4 被用户 5 上锁。
lockingTree.upgrade(0, 1); // 返回 true ,因为节点 0 未上锁且至少有一个被上锁的子孙节点(节点 4)。// 节点 0 被用户 1 上锁,节点 4 变为未上锁。
lockingTree.lock(0, 1);    // 返回 false ,因为节点 0 已经被上锁了。

提示:

  • n == parent.length
  • 2 <= n <= 2000
  • 对于 i != 0 ,满足 0 <= parent[i] <= n - 1
  • parent[0] == -1
  • 0 <= num <= n - 1
  • 1 <= user <= 104
  • parent 表示一棵合法的树。
  • lock ,unlock 和 upgrade 的调用 总共 不超过 2000 次。

实现代码与解析:

模拟 + dfs

class LockingTree {
public:vector<int> h = vector<int>(2010, -1), e = vector<int>(2010, 0), ne = vector<int>(2010, 0);vector<int> parent; // 方便后面向上遍历int idx = 0; // 邻接表vector<int> flag = vector<int>(2010, 0); // 记录是否上锁void add(int a, int b){e[idx] = b; ne[idx] = h[a]; h[a] = idx++;}LockingTree(vector<int>& parent) {for (int i = 1; i < parent.size(); i++) {add(parent[i], i); // 连接}this->parent = parent;}bool lock(int num, int user) {if (flag[num]) return false; // 已经有人上锁,不能再上flag[num] = user;return true;}bool unlock(int num, int user) {if (flag[num] != user) return false; // 非你上,不能解flag[num] = 0;return true;}bool upgrade(int num, int user) {// 当前节点和其祖先不能有锁for (int i = num; ~i; i = parent[i]) {if (flag[i]) return false;}// 子孙必须有至少一个上锁if (!hasLockedDescendant(num)) return false;// 解锁所有子孙节点unlockDescendants(num);// 上锁当前节点flag[num] = user;return true;}bool hasLockedDescendant(int num) {for (int i = h[num]; i != -1; i = ne[i]) {int child = e[i];if (flag[child] || hasLockedDescendant(child)) {return true;}}return false;}void unlockDescendants(int num) {for (int i = h[num]; i != -1; i = ne[i]) {int child = e[i];if (flag[child]) {flag[child] = 0;}unlockDescendants(child);}}
};

原理思路:

        其实只有upgrade麻烦一点,先利用parent数组,判断一下自己和祖先是否未上锁,其次判断子孙节点是否至少有一个上锁,如果满足以上条件,将子孙解锁并给自己上锁。注意顺序,和解锁时机,以免印象后续操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android开发MVP架构记录

Android开发MVP架构记录 安卓的MVP&#xff08;Model-View-Presenter&#xff09;架构是一种常见的软件设计模式&#xff0c;用于帮助开发者组织和分离应用程序的不同组成部分。MVP架构的目标是将应用程序的业务逻辑&#xff08;Presenter&#xff09;、用户界面&#xff08;V…

Mybatis自动映射Java对象 与 MySQL8后的JSON数据

文章目录 Mybatis自动映射Java对象 与 MySQL8后的JSON数据1.转化成为正常Json类型1.1 JsonTypeHander1.2 ListJsonTypeHandler 负责List<T> 类型1.3 实体类1.4 mapper1.5 测试类 2. 存储为携带类型的Json Mybatis自动映射Java对象 与 MySQL8后的JSON数据 1.转化成为正常…

【密码学补充知识】

&#x1f511;密码学&#x1f512;概述 &#x1f4d5; 1.基本概念 明文 &#xff1a; 要交换的信息 密文 &#xff1a; 明文经过一组规则变换成看似没有意义的随机消息。 加密 &#xff1a; 明文经过一组规则变换成密文的过程 解密 &#xff1a; 密文恢复出明文的过程 加…

MT1184矩形相交 题解【超详细】

目录 题目 样例 题目解析 代码 图解 矩形相交 题目 输入2个矩形的左上角和右下角两个点的坐标值(x&#xff0c;y)&#xff0c;判断2个矩形是否相交&#xff0c;输出YES或者NO。矩形的边应与x&#xff0c;y轴相平行。假定输入坐标能顺利构成矩形&#xff0c;不考虑无效矩形…

macOS使用官方安装包安装python

新手程序员可能想知道如何在 Mac 上正确安装 Python&#xff0c;这里介绍在 macOS 上安装 Python 的方法。 操作步骤 1.从 Python 官方网站 (python.org) 下载最新的 Python 版本. 单击 macOS 链接并选择最新的 Python 版本。 2.下载完成后&#xff0c;双击包开始安装Python…

第6讲:v-for使用

目录 1.循环遍历 2.v-for遍历整形变量&#xff08;99乘法表&#xff09; 3.v-for遍历普通数组 4.v-for遍历数组对象 1.循环遍历 v-for指令基于一个数组渲染一个列表&#xff0c;它和JavaScript的遍历语法相似&#xff1a; v-for”item in list” list 是一个数组&#xff0c; i…

windows平台 git bash使用

打开所在需要git管理的目录,鼠标右键open Git BASH here 这样就直接进来,不需要windows dos窗口下麻烦的切路径&#xff0c;windows和linux 路径方向不一致 (\ /) 然后git init 建立本地仓库,接下来就是git相关的操作了. 图形化界面查看 打开所在需要git管理的目录,鼠标右键…

软考高级架构师下篇-17安全架构设计理论与实践

目录 1. 引言信息安全面临的威胁2. 安全体系架构的范围3.典型安全模型4.信息安全整体架构设计5.数据库系统安全设计6.系统架构脆弱性分析7.安全架构设计实践8. 前文回顾1. 引言 随着科技的发展,信息系统的安全受到诸多方面的威胁,设计信息系统安全架构需要从各个方面考虑,这…

如何通过优化Read-Retry机制降低SSD读延迟?

近日,小编发现发表于2021论文中,有关于优化Read-Retry机制降低SSD读延迟的研究,小编这里给大家分享一下这篇论文的核心的思路,感兴趣的同学可以,可以在【存储随笔】VX公号后台回复“Optimizing Read-Retry”获取下载链接。 本文中主要基于Charge Trap NAND架构分析。NAND基…

buuctf-[WUSTCTF2020]朴实无华

打开环境就这么一句话 先打开index.php,但是没有什么 查看了下网络 看到gzip和php 我试了试www.zip 还有index.phps&#xff0c;也是一样的&#xff0c;都没找到文件 于是我想到用御剑扫&#xff0c;但是我好像线程太长了&#xff0c;一个没扫到&#xff0c;我就想到用dirsea…

人工智能AI 全栈体系(六)

第一章 神经网络是如何实现的 这些年神经网络的发展越来越复杂&#xff0c;应用领域越来越广&#xff0c;性能也越来越好&#xff0c;但是训练方法还是依靠 BP 算法。也有一些对 BP 算法的改进算法&#xff0c;但是大体思路基本是一样的&#xff0c;只是对 BP 算法个别地方的一…

Jmeter配置性能监控插件

一、版本不兼容时&#xff0c;有报错 1、当jmeter版本比较高时&#xff0c;只需要从官网安装jmeter-plugins-manager-1.10.jar一个包 2、当jmeter版本较低时&#xff0c;安装JMeterPlugins-Extras-1.4.0.zip、JMeterPlugins-Standard-1.4.0.zip内两个jar包 3、服务器上传文件…

PTE深度了解(一)

目录 PTE模板开始大审查吗&#xff1f;我的模板还能用吗&#xff1f; 使用模版&#xff0c;不会额外扣你分 类型一&#xff08;前20秒说模版&#xff09; 类型二&#xff08;老实巴交&#xff09; 类型三&#xff08;就是都说简单句&#xff09; 1.查重复 2.增加内容分识…

Android Jetpack组件架构 :LiveData的使用和原理

Android Jetpack组件架构&#xff1a; LiveDate的使用和原理 导言 继Lifecycle组件之后我们接下来要介绍的就是LiveDate组件&#xff0c;所谓LiveDate字面意思上就是有声明的数据&#xff0c;当数据有改动时该组件可以感知到这个操作并将该事件通知到其观察者&#xff0c;这样…

Linux基础指令(五)

目录 前言1. 打包和压缩1.1 是什么1.2 为什么1.3 怎么办&#xff1f; 2. zip & unzip3. tar 指令结语&#xff1a; 前言 欢迎各位伙伴来到学习 Linux 指令的 第五天&#xff01;&#xff01;&#xff01; 在上一篇文章 Linux基本指令(四) 当中&#xff0c;我们学习了 fin…

git --- 基础介绍

git --- 基础介绍 git 是什么git --- 工作区, 暂存区, 资源库git --- 文件状态git --- branch 和 HEADgit --- 一次正常的git提交流程 git 是什么 Git是一款分布式源代码管理工具(版本控制工具)Git和其他传统版本控制系统比较: 传统的版本控制系统(例如 SVN)是基于差异的版本控…

回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于RF-Adaboost随机森林结合…

mac 解决 vscode 权限不足问题,Insufficient permissions

commod 空格&#xff0c;输入终端并打开写入指令 sudo chown -R xxxxxx1 xxxxx2&#xff08;例如我的sudo chown -R admin Desktop&#xff0c;具体参数查看下方&#xff09; x1: 用户名&#xff0c;可通过左上角查看 x2: 目标文件夹。可以另起一个终端&#xff0c;用cd 和 l…

vue+element项目创建步骤

一、创建vue项目步骤 要创建一个Vue Element UI的项目&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1.确保你已经安装了Node.js和npm&#xff08;Node.js的包管理器&#xff09;。你可以在命令行中运行以下命令来检查它们是否已经安装&#xff1a; node -vnpm -v2.使…

《开发实战》18 | 数据存储:NoSQL与RDBMS如何取长补短、相辅相成?

取长补短之 Redis vs MySQL 做一个简单测试&#xff0c;分别填充 10 万条数据到 Redis 和 MySQL 中。MySQL 中的 name字段做了索引&#xff0c;相当于 Redis 的 Key&#xff0c;data 字段为 100 字节的数据&#xff0c;相当于 Redis 的Value。在我的电脑上&#xff0c;使用 wr…