LC.P1993[树上的操作]

方法一:DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class LockingTree {

int[] locked;
int[] parent;
List<Integer>[] children;

public LockingTree(int[] parent) {
int n = parent.length;
locked = new int[n];
this.parent = parent;
children = new List[n];
Arrays.fill(locked, -1);
Arrays.setAll(children, k -> new ArrayList<>());
for (int i = 1; i < n; i++) {
children[parent[i]].add(i);
}
}

public boolean lock(int num, int user) {
if (locked[num] == -1) {
locked[num] = user;
return true;
}
return false;
}

public boolean unlock(int num, int user) {
if (locked[num] == user) {
locked[num] = -1;
return true;
}
return false;
}

public boolean upgrade(int num, int user) {
int x = num;
// 判断当前节点及其祖先节点是否被上锁
while (x != -1) {
if (locked[x] != -1) {
return false;
}
x = parent[x];
}
boolean[] find = new boolean[1];
// 判断当前节点的子孙节点是否被上锁
dfs(num, find);
if (!find[0]) {
return false;
}
locked[num] = user;
return true;
}

private void dfs(int x, boolean[] find) {
for (int y : children[x]) {
if (locked[y] != -1) {
locked[y] = -1;
find[0] = true;
}
dfs(y, find);
}
}
}

/**
* 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);
*/
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$