Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f076412

Browse files
committed
Add solution #1993
1 parent f5d35cc commit f076412

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 1,674 LeetCode solutions in JavaScript
1+
# 1,675 LeetCode solutions in JavaScript
22

33
[https://leetcodejavascript.com](https://leetcodejavascript.com)
44

@@ -1528,6 +1528,7 @@
15281528
1987|[Number of Unique Good Subsequences](./solutions/1987-number-of-unique-good-subsequences.js)|Hard|
15291529
1991|[Find the Middle Index in Array](./solutions/1991-find-the-middle-index-in-array.js)|Easy|
15301530
1992|[Find All Groups of Farmland](./solutions/1992-find-all-groups-of-farmland.js)|Medium|
1531+
1993|[Operations on Tree](./solutions/1993-operations-on-tree.js)|Medium|
15311532
1996|[The Number of Weak Characters in the Game](./solutions/1996-the-number-of-weak-characters-in-the-game.js)|Medium|
15321533
2000|[Reverse Prefix of Word](./solutions/2000-reverse-prefix-of-word.js)|Easy|
15331534
2011|[Final Value of Variable After Performing Operations](./solutions/2011-final-value-of-variable-after-performing-operations.js)|Easy|

solutions/1993-operations-on-tree.js

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* 1993. Operations on Tree
3+
* https://leetcode.com/problems/operations-on-tree/
4+
* Difficulty: Medium
5+
*
6+
* You are given a tree with n nodes numbered from 0 to n - 1 in the form of a parent array
7+
* parent where parent[i] is the parent of the ith node. The root of the tree is node 0,
8+
* so parent[0] = -1 since it has no parent. You want to design a data structure that
9+
* allows users to lock, unlock, and upgrade nodes in the tree.
10+
*
11+
* The data structure should support the following functions:
12+
* - Lock: Locks the given node for the given user and prevents other users from locking
13+
* the same node. You may only lock a node using this function if the node is unlocked.
14+
* - Unlock: Unlocks the given node for the given user. You may only unlock a node using
15+
* this function if it is currently locked by the same user.
16+
* - Upgrade: Locks the given node for the given user and unlocks all of its descendants
17+
* regardless of who locked it. You may only upgrade a node if all 3 conditions are true:
18+
* - The node is unlocked,
19+
* - It has at least one locked descendant (by any user), and
20+
* - It does not have any locked ancestors.
21+
*
22+
* Implement the LockingTree class:
23+
* - LockingTree(int[] parent) initializes the data structure with the parent array.
24+
* - lock(int num, int user) returns true if it is possible for the user with id user to lock
25+
* the node num, or false otherwise. If it is possible, the node num will become locked by
26+
* the user with id user.
27+
* - unlock(int num, int user) returns true if it is possible for the user with id user to
28+
* unlock the node num, or false otherwise. If it is possible, the node num will become unlocked.
29+
* - upgrade(int num, int user) returns true if it is possible for the user with id user to
30+
* upgrade the node num, or false otherwise. If it is possible, the node num will be upgraded.
31+
*/
32+
33+
/**
34+
* @param {number[]} parent
35+
*/
36+
var LockingTree = function(parent) {
37+
this.parent = parent;
38+
this.locked = new Map();
39+
this.children = new Array(parent.length).fill().map(() => []);
40+
for (let i = 1; i < parent.length; i++) {
41+
this.children[parent[i]].push(i);
42+
}
43+
};
44+
45+
/**
46+
* @param {number} num
47+
* @param {number} user
48+
* @return {boolean}
49+
*/
50+
LockingTree.prototype.lock = function(num, user) {
51+
if (this.locked.has(num)) return false;
52+
this.locked.set(num, user);
53+
return true;
54+
};
55+
56+
/**
57+
* @param {number} num
58+
* @param {number} user
59+
* @return {boolean}
60+
*/
61+
LockingTree.prototype.unlock = function(num, user) {
62+
if (!this.locked.has(num) || this.locked.get(num) !== user) return false;
63+
this.locked.delete(num);
64+
return true;
65+
};
66+
67+
/**
68+
* @param {number} num
69+
* @param {number} user
70+
* @return {boolean}
71+
*/
72+
LockingTree.prototype.upgrade = function(num, user) {
73+
if (this.locked.has(num)) return false;
74+
75+
let node = num;
76+
while (node !== -1) {
77+
if (this.locked.has(node)) return false;
78+
node = this.parent[node];
79+
}
80+
81+
const descendants = [];
82+
const queue = [num];
83+
let hasLockedDescendant = false;
84+
85+
while (queue.length) {
86+
const curr = queue.shift();
87+
if (this.locked.has(curr)) {
88+
hasLockedDescendant = true;
89+
descendants.push(curr);
90+
}
91+
queue.push(...this.children[curr]);
92+
}
93+
94+
if (!hasLockedDescendant) return false;
95+
96+
for (const descendant of descendants) {
97+
this.locked.delete(descendant);
98+
}
99+
this.locked.set(num, user);
100+
return true;
101+
};

0 commit comments

Comments
 (0)