You are given a tree with n nodes numbered from 0 to n - 1 in the form of a parent array parent where parent[i] is the parent of the ith node. The root of the tree is node 0, so parent[0] = -1 since it has no parent.

You need to design a data structure that supports three operations:

  • Lock: Locks the given node for the given user and prevents other users from locking the same node. You may only lock a node if it is currently unlocked.
  • Unlock: Unlocks the given node for the given user. You may only unlock a node if it is currently locked by the same user.
  • Upgrade: Locks the given node for the given user and unlocks all of its descendants. You may only upgrade a node if: (1) the node is unlocked, (2) it has at least one locked descendant, and (3) it does not have any locked ancestors.

Implement the LockingTree class with constructor and three methods as described above.

Input & Output

Example 1 — Basic Operations
$ Input: parent = [-1,0,0,1,1,2,2], operations = [["lock",2,2],["unlock",2,3],["unlock",2,2],["lock",4,5],["upgrade",0,1]]
Output: [true,false,true,true,true]
💡 Note: Lock node 2 for user 2 (success). Try unlock node 2 by user 3 (fail - wrong user). Unlock node 2 by user 2 (success). Lock node 4 for user 5 (success). Upgrade node 0 for user 1 (success - unlocks node 4, locks node 0).
Example 2 — Upgrade Conditions
$ Input: parent = [-1,0,3,1,1], operations = [["lock",4,2],["lock",3,3],["upgrade",1,1]]
Output: [true,true,false]
💡 Note: Lock nodes 4 and 3. Try upgrade node 1 - fails because ancestor 0 could be locked or node 3 (child of 1) is locked but 3 is not a descendant through the upgrade path.

Constraints

  • n == parent.length
  • 2 ≤ n ≤ 1000
  • 0 ≤ parent[i] ≤ n - 1 for i ≠ 0
  • parent[0] == -1
  • 0 ≤ num ≤ n - 1
  • 1 ≤ user ≤ 104
  • At most 2000 calls will be made to lock, unlock, and upgrade

Visualization

Tap to expand
Operations on Tree INPUT Tree Structure 0 1 2 3 4 5 6 parent = [-1,0,0,1,1,2,2] Operations: 1. lock(2, user2) 2. unlock(2, user3) 3. unlock(2, user2) 4. lock(4, user5) 5. upgrade(0, user1) Children Map: 0: [1,2], 1: [3,4], 2: [5,6] ALGORITHM STEPS 1 lock(2, user2) Node 2 unlocked, lock it Result: TRUE 2 unlock(2, user3) User3 != User2 (locker) Result: FALSE 3 unlock(2, user2) User2 == User2, unlock OK Result: TRUE 4 lock(4, user5) Node 4 unlocked, lock it Result: TRUE 5 upgrade(0, user1) Node 0 unlocked, has locked descendant (4), no ancestor locked. Lock 0, unlock 4 Result: TRUE Children Map Optimization Fast DFS to find locked descendants O(n) per upgrade operation FINAL RESULT Output Array: true false true true true Final Tree State: 0 locked:u1 1 2 3 4 5 6 Summary 4 successful, 1 failed operation Key Insight: Using a Children Map allows O(1) access to children of any node, making DFS traversal efficient. Lock/Unlock are O(h) for ancestor check. Upgrade uses DFS to find and unlock all locked descendants. This optimization avoids repeated parent array traversals and provides direct child access. TutorialsPoint - Operations on Tree | Optimized with Children Map
Asked in
Google 25 Microsoft 18 Amazon 15
28.0K Views
Medium Frequency
~35 min Avg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen