1376. 通知所有员工所需的时间
思路:(方法1:dfs)dfs是最容易想到的,这是遍历树结构常用的一种递归算法,用hashmap来保存这个有向图结构(也类似于多叉树),从head节点开始递归遍历他的子节点,相当于计算每一条从head出发到各个叶子节点的time取最大值即可。
class Solution {//dfs
// 通知所有员工所需的时间
public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
if (n == 1) {
return 0;
}
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < manager.length; i++) {
map.computeIfAbsent(manager[i], v -> new ArrayList<>()).add(i);
}
return dfs(map, headID, informTime);
}
private int dfs(Map<Integer, List<Integer>> map, int cur, int[] informTime) {
if(!map.containsKey(cur)) return 0;
// 当前员工无下属,那么花费时间为0
int max = 0;
// 快的要等慢的,也就是当所有员工都通知到以后才视为这次通知完成
for (Integer nei : map.get(cur)) {
max = Math.max(max, dfs(map, nei, informTime));
}
return informTime[cur] + max;
}
}
思路:(方法2:bfs)看到大多数答案都是dfs所以决定试一下bfs练练手,但是一开始我想的bfs方法是错误的,一开始我以为在遍历每一层的时候取该层的最大值即可,后来发现并不是所有的叶子节点都在同一层,所以这种想法是错误的。我使用time数组来存储到达每个节点时的时间,这样就不需要再定义一个多余的数据结构类了。然后使用bfs的基本遍历方法逐层遍历并同时一层层更新time数组,用max记录最大值,迭代后的max即为最终结果。
class Solution {//bfs
// 通知所有员工所需的时间
public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
if (n == 1) {
return 0;
}
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < manager.length; i++) {
map.computeIfAbsent(manager[i], v -> new ArrayList<>()).add(i);
}
int max = 0;
int[] time = new int[manager.length];
LinkedList<Integer> q = new LinkedList<>();
q.add(headID);
while(!q.isEmpty()) {
int i = q.poll(); //遍历当前员工的HashMap,将下属的员工加入队列
for(int son:map.getOrDefault(i,new ArrayList<>())){
q.offer(son);
time[son] = time[i] + informTime[i];
}
max = Math.max(time[i],max);
}
return max;
}
}