Class LockingTree

java.lang.Object
g1901_2000.s1993_operations_on_tree.LockingTree

public class LockingTree extends Object
1993 - Operations on Tree.<p>Medium</p> <p>You are given a tree with <code>n</code> nodes numbered from <code>0</code> to <code>n - 1</code> in the form of a parent array <code>parent</code> where <code>parent[i]</code> is the parent of the <code>i<sup>th</sup></code> node. The root of the tree is node <code>0</code>, so <code>parent[0] = -1</code> since it has no parent. You want to design a data structure that allows users to lock, unlock, and upgrade nodes in the tree.</p> <p>The data structure should support the following functions:</p> <ul> <li><strong>Lock: Locks</strong> the given node for the given user and prevents other users from locking the same node. You may only lock a node using this function if the node is unlocked.</li> <li><strong>Unlock: Unlocks</strong> the given node for the given user. You may only unlock a node using this function if it is currently locked by the same user.</li> <li><strong>Upgrade: Locks</strong> the given node for the given user and <strong>unlocks</strong> all of its descendants <strong>regardless</strong> of who locked it. You may only upgrade a node if <strong>all</strong> 3 conditions are true: <ul> <li>The node is unlocked,</li> <li>It has at least one locked descendant (by <strong>any</strong> user), and</li> <li>It does not have any locked ancestors.</li> </ul> </li> </ul> <p>Implement the <code>LockingTree</code> class:</p> <ul> <li><code>LockingTree(int[] parent)</code> initializes the data structure with the parent array.</li> <li><code>lock(int num, int user)</code> returns <code>true</code> if it is possible for the user with id <code>user</code> to lock the node <code>num</code>, or <code>false</code> otherwise. If it is possible, the node <code>num</code> will become <strong>locked</strong> by the user with id <code>user</code>.</li> <li><code>unlock(int num, int user)</code> returns <code>true</code> if it is possible for the user with id <code>user</code> to unlock the node <code>num</code>, or <code>false</code> otherwise. If it is possible, the node <code>num</code> will become <strong>unlocked</strong>.</li> <li><code>upgrade(int num, int user)</code> returns <code>true</code> if it is possible for the user with id <code>user</code> to upgrade the node <code>num</code>, or <code>false</code> otherwise. If it is possible, the node <code>num</code> will be <strong>upgraded</strong>.</li> </ul> <p><strong>Example 1:</strong></p> <p><img src="https://assets.leetcode.com/uploads/2021/07/29/untitled.png" alt="" /></p> <p><strong>Input</strong></p> <p>[&ldquo;LockingTree&rdquo;, &ldquo;lock&rdquo;, &ldquo;unlock&rdquo;, &ldquo;unlock&rdquo;, &ldquo;lock&rdquo;, &ldquo;upgrade&rdquo;, &ldquo;lock&rdquo;]</p> <p>[<a href="-1,-0,-0,-1,-1,-2,-2">-1, 0, 0, 1, 1, 2, 2</a>, [2, 2], [2, 3], [2, 2], [4, 5], [0, 1], [0, 1]]</p> <p><strong>Output:</strong> [null, true, false, true, true, true, false]</p> <p><strong>Explanation:</strong></p> <pre><code> LockingTree lockingTree = new LockingTree([-1, 0, 0, 1, 1, 2, 2]); lockingTree.lock(2, 2); // return true because node 2 is unlocked. // Node 2 will now be locked by user 2. lockingTree.unlock(2, 3); // return false because user 3 cannot unlock a node locked by user 2. lockingTree.unlock(2, 2); // return true because node 2 was previously locked by user 2. // Node 2 will now be unlocked. lockingTree.lock(4, 5); // return true because node 4 is unlocked. // Node 4 will now be locked by user 5. lockingTree.upgrade(0, 1); // return true because node 0 is unlocked and has at least one locked descendant (node 4). // Node 0 will now be locked by user 1 and node 4 will now be unlocked. lockingTree.lock(0, 1); // return false because node 0 is already locked. </code></pre> <p><strong>Constraints:</strong></p> <ul> <li><code>n == parent.length</code></li> <li><code>2 <= n <= 2000</code></li> <li><code>0 <= parent[i] <= n - 1</code> for <code>i != 0</code></li> <li><code>parent[0] == -1</code></li> <li><code>0 <= num <= n - 1</code></li> <li><code>1 <= user <= 10<sup>4</sup></code></li> <li><code>parent</code> represents a valid tree.</li> <li>At most <code>2000</code> calls <strong>in total</strong> will be made to <code>lock</code>, <code>unlock</code>, and <code>upgrade</code>.</li> </ul>
  • Constructor Details

    • LockingTree

      public LockingTree(int[] parent)
  • Method Details

    • lock

      public boolean lock(int num, int user)
    • unlock

      public boolean unlock(int num, int user)
    • upgrade

      public boolean upgrade(int num, int user)