5848. 樹上的操作

給你一棵 n 個節點的樹,編號從 0 到 n - 1 ,以父節點數組 parent 的形式給出,其中 parent[i] 是第 i 個節點的父節點。樹的根節點為 0 號節點,所以 parent[0] = -1 ,因為它沒有父節點。你想要設計一個數據結構實現樹里面對節點的加鎖,解鎖和升級操作。

數據結構需要支持如下函數:

  • Lock:指定用戶給指定節點 上鎖 ,上鎖后其他用戶將無法給同一節點上鎖。只有當節點處于未上鎖的狀態下,才能進行上鎖操作。
  • Unlock:指定用戶給指定節點 解鎖 ,只有當指定節點當前正被指定用戶鎖住時,才能執行該解鎖操作。
  • Upgrade:指定用戶給指定節點 上鎖 ,并且將該節點的所有子孫節點 解鎖 。只有如下 3 個條件 全部 滿足時才能執行升級操作:
  1. 指定節點當前狀態為未上鎖。
  2. 指定節點至少有一個上鎖狀態的子孫節點(可以是 任意 用戶上鎖的)。
  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 次。

解題思路

使用map維護被鎖節點和加鎖者的關系,再使用一個map維護父節點和對應子節點之間的關系

lock

判斷是否有鎖,如果沒有,則可以直接加鎖

unlock

判斷當前鎖的加鎖者是否為自己

upgrade

  1. 先向上遍歷祖先節點和加鎖節點,判斷是否有加鎖
  2. 再遍歷子孫節點,判斷是否加鎖
  3. 給所有子孫節點解鎖,給當前節點加鎖

代碼

    class LockingTree {int[] p;Map<Integer, Integer> locked = new HashMap<>();Map<Integer,Set<Integer>> child=new HashMap<>();public LockingTree(int[] parent) {p = parent;for (int i = 0; i < parent.length; i++) {if (!child.containsKey(p[i]))child.put(p[i],new HashSet<>());child.get(p[i]).add(i);}}public boolean lock(int num, int user) {if (locked.containsKey(num) )return false;locked.put(num, user);return true;}public boolean unlock(int num, int user) {if (locked.containsKey(num) && locked.get(num) == user) {locked.remove(num);return true;} else return false;}public boolean dfs(int num) {while (num!=-1){if(locked.containsKey(num))return false;num=p[num];}return true;}public boolean ddfs(int num,int f) {if (locked.containsKey(num)&&num!=f){return true;}boolean res=false;if (child.containsKey(num)){for (Integer integer : child.get(num)) {res|=ddfs(integer,f);}}return res;}public void dddfs(int num) {locked.remove(num);if (child.containsKey(num)){for (Integer integer : child.get(num)) {dddfs(integer);}}}public boolean upgrade(int num, int user) {if (dfs(num)&&ddfs(num,num)){dddfs(num);locked.put(num, user);return true;}return false;}}/*** 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);*//*** 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);*/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390145.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390145.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390145.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

了解如何通過Python使用SQLite數據庫

SQLite is a very easy to use database engine included with Python. SQLite is open source and is a great database for smaller projects, hobby projects, or testing and development.SQLite是Python附帶的非常易于使用的數據庫引擎。 SQLite是開源的&#xff0c;是用于…

32位JDK和64位JDK

32位和64位系統在計算機領域中常常提及&#xff0c;但是仍然很多人不知道32位和64位的區別&#xff0c;所以本人在網上整理了一些資料&#xff0c;并希望可以與大家一起分享。對于32位和64位之分&#xff0c;本文將分別從處理器&#xff0c;操作系統&#xff0c;JVM進行講解。 …

中小企業如何選擇OA協同辦公產品?最全的對比都在這里了

對于中小企業來說&#xff0c;傳統的OA 產品&#xff0c;如泛微、藍凌、致遠、華天動力等存在價格高、使用成本高、二次開發難等特點&#xff0c;并不適合企業的協同管理。 國內OA市場也出現了一批輕便、低價的OA產品&#xff0c;本文針對以下幾款適合中小企業的OA產品在功能、…

python緩沖區_如何在Python中使用Google的協議緩沖區

python緩沖區When people who speak different languages get together and talk, they try to use a language that everyone in the group understands. 當說不同語言的人聚在一起聊天時&#xff0c;他們會嘗試使用小組中每個人都能理解的語言。 To achieve this, everyone …

PowerDesigner16中的對象無效,不允許有擴展屬性 問題的解決

PowerDesigner16中的對象無效&#xff0c;不允許有擴展屬性 消息 15135&#xff0c;級別 16&#xff0c;狀態 1&#xff0c;過程 sp_addextendedproperty&#xff0c;第 37 行 對象無效。XXXXXXX 不允許有擴展屬性&#xff0c;或對象不存在。 把 execute sp_addextendedpropert…

Elasticsearch學習(2)—— 常見術語

為什么80%的碼農都做不了架構師&#xff1f;>>> cluster (集群)&#xff1a;一個或多個擁有同一個集群名稱的節點組成了一個集群。每個集群都會自動選出一個主節點&#xff0c;如果該主節點故障&#xff0c;則集群會自動選出新的主節點來替換故障節點。 node (節點…

67. 二進制求和

67. 二進制求和 給你兩個二進制字符串&#xff0c;返回它們的和&#xff08;用二進制表示&#xff09;。 輸入為 非空 字符串且只包含數字 1 和 0。 示例 1: 輸入: a “11”, b “1” 輸出: “100” 示例 2: 輸入: a “1010”, b “1011” 輸出: “10101” 提示&…

前端開發有哪些技術棧要掌握_為什么要掌握前端開發的這四個主要概念

前端開發有哪些技術棧要掌握After working as a front-end developer for three years, I have been able to summarize what I feel are the four major concepts of front-end development. Knowing and studying these four areas will make you stand out from the crowd.在…

python中的序列化與反序列化

之前&#xff0c;在學習python時&#xff0c;一直弄不明白pickle和json模塊的序列化和反序例化之間的區別和用法&#xff0c;最近閑來有時間&#xff0c;重新研究了這兩個模塊&#xff0c;也算是基本搞明白他們之中的區別了。 用于序列化的兩個模塊&#xff0c; json&#xff0…

1114. 按序打印

1114. 按序打印 我們提供了一個類&#xff1a; public class Foo { public void first() { print(“first”); } public void second() { print(“second”); } public void third() { print(“third”); } } 三個不同的線程 A、B、C 將會共用一個 Foo 實例。 一個將會調用 …

2018年應用交付控制器市場將發生重大變化

應用交付控制器&#xff08;ADC&#xff09;一直以來都是基礎設施的關鍵部分。它們位于應用程序和基礎架構之間&#xff0c;是唯一可以同時使用應用程序和網絡語言的技術。IT行業正在經歷一個快速的現代化進程&#xff0c;包含諸如軟件定義的網絡、云、容器等其他計劃對基礎設施…

如何測試一個水杯

關于一個水杯如何測試&#xff1f;這個被認為是測試界最為經驗的面試題了&#xff0c;下面是我的回答思路&#xff1a; 對于一個軟件的測試&#xff0c;重點是測試的思路以及測試的全面性的體現。 軟件測試應該先重點再次重點&#xff0c;對于軟件而言重點自然在于功能測試&…

1115. 交替打印FooBar

1115. 交替打印FooBar 我們提供一個類&#xff1a; class FooBar {public void foo() {for (int i 0; i < n; i) {print("foo");}}public void bar() {for (int i 0; i < n; i) {print("bar");}} }兩個不同的線程將會共用一個 FooBar 實例。其中…

IntelliJ IDEA 運行 Maven 項目

1.官方文檔說IntelliJ IDEA已經自身集成了maven&#xff0c;則不用勞心去下載maven 2.導入一個程序&#xff0c;看是否是maven程序的關鍵在于工程之中有沒有pom.xml這個文件&#xff0c;比如這里 3.為這個工程配置好服務器3.1 點擊“Edit Configurations”3.2 進入Run/Debug C…

資深老鳥整理,Java接口自動化測試總結,從0到1自動化...

這幾年接口自動化變得越來越熱門&#xff0c;相對比于UI自動化&#xff0c;接口自動化有一些優勢 1&#xff09;運行比UI更穩定&#xff0c;讓BUG更容易定位 2&#xff09;UI自動化維護成本太高&#xff0c;接口相對低一些 接口測試其實有很多方式&#xff0c;主要有兩種&…

parcel react_如何使用Parcel設置React應用

parcel reactFor a long time Webpack was one of the biggest barriers-to-entry for someone wanting to learn React. Theres a lot of boilerplate configuration that can be confusing, especially if youre new to React. 長期以來&#xff0c; Webpack一直是想要學習Re…

1117. H2O 生成

1117. H2O 生成 現在有兩種線程&#xff0c;氧 oxygen 和氫 hydrogen&#xff0c;你的目標是組織這兩種線程來產生水分子。 存在一個屏障&#xff08;barrier&#xff09;使得每個線程必須等候直到一個完整水分子能夠被產生出來。 氫和氧線程會被分別給予 releaseHydrogen 和…

pdf 字體和圖片抽取

2019獨角獸企業重金招聘Python工程師標準>>> #安裝mutoos sudo apt-get install mupdf-tools #抽取字體 mutool extract LTN20180531052_C.pdf 轉載于:https://my.oschina.net/colin86/blog/1842412

推箱子2-向右推!_保持冷靜,砍箱子-銀行

推箱子2-向右推!Hack The Box (HTB) is an online platform allowing you to test your penetration testing skills. It contains several challenges that are constantly updated. Some of them are simulating real world scenarios and some of them lean more towards a …

611. 有效三角形的個數

611. 有效三角形的個數 給定一個包含非負整數的數組&#xff0c;你的任務是統計其中可以組成三角形三條邊的三元組個數。 示例 1: 輸入: [2,2,3,4] 輸出: 3 解釋: 有效的組合是: 2,3,4 (使用第一個 2) 2,3,4 (使用第二個 2) 2,2,3注意: 數組長度不超過1000。數組里整數的范…