题目:
例子:
思路:
- 初始化数组,定义一个parent数组来接收初始化参数。
- 定义一个locked数组,和parent数组同样大小的数组用来存放上锁和解锁的信息。
- 定义一个邻接矩阵来存储子节点信息。
- 对于上锁和解锁,由于是一对一的关系,即一个节点只能被一个用户上锁,因此每次上锁时,只需要将locked数组中的值置为用户即可。
- 对于更新,首先可以循环判断父节点是否上锁,之后,通过dfs深度遍历来判断子节点是否存在上锁,若存在,则将其解锁,并返回true;
代码:
class LockingTree {
int[] parent;
int[] locked;
List<Integer>[] children;
public LockingTree(int[] parent) {
this.parent = parent;
locked = new int[parent.length];
children = new List[parent.length];
Arrays.setAll(children, i -> new ArrayList<>());
for (int i = 1; i < parent.length; i++) {
children[parent[i]].add(i);
}
}
public boolean lock(int num, int user) {
if (locked[num] == 0) {
locked[num] = user;
return true;
}
return false;
}
public boolean unlock(int num, int user) {
if (locked[num] == user) {
locked[num] = 0;
return true;
}
return false;
}
public boolean upgrade(int num, int user) {
int temp = num;
//判断父节点
while (temp != -1) {
if (locked[temp] != 0) {
return false;
}
temp = parent[temp];
}
//判断子节点
boolean[] find = new boolean[1];
dfs(num, find);
if (!find[0]) {
return false;
}
locked[num] = user;
return true;
}
private void dfs(int num, boolean[] find) {
for (int son : children[num]) {
if (locked[son] != 0) {
locked[son] = 0;
find[0] = true;
}
dfs(son, find);
}
}
}