通知所有员工所需的时间【LC1376】
公司里有
n
名员工,每个员工的 ID 都是独一无二的,编号从0
到n - 1
。公司的总负责人通过headID
进行标识。在
manager
数组中,每个员工都有一个直属负责人,其中manager[i]
是第i
名员工的直属负责人。对于总负责人,manager[headID] = -1
。题目保证从属关系可以用树结构显示。公司总负责人想要向公司所有员工通告一条紧急消息。他将会首先通知他的直属下属们,然后由这些下属通知他们的下属,直到所有的员工都得知这条紧急消息。
第
i
名员工需要informTime[i]
分钟来通知它的所有直属下属(也就是说在informTime[i]
分钟后,他的所有直属下属都可以开始传播这一消息)。返回通知所有员工这一紧急消息所需要的 分钟数 。
写出了方法一
自顶向下
-
思路
当总负责人发送完通知后,直属下属们可以同时向他们的下属发送通知,因此通知所有员工所需要的时间为直属下属通知其下面的员工的最大时间,因此可以使用dfs实现
-
实现
- 首先通过矩阵存储每位领导的下属
- 然后使用dfs搜索,
dfs(p)
的含义为通知ID为p的负责人下面的所有员工所需要的时间,因此dfs(headID)
即为结果
class Solution { List<Integer>[] list; int[] informTime; public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { list = new List[n]; Arrays.setAll(list, e -> new ArrayList<>()); int res = 0; this.informTime = informTime; for (int i = 0; i < n; i++){ if (manager[i] != -1){ list[manager[i]].add(i); } } return dfs(headID); } public int dfs(int p){ if (list[p].size() == 0) return 0; int res = 0; for (int u : list[p]){ res = Math.max(res, dfs(u)); } return res + informTime[p]; } }
-
复杂度
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
自底向上
-
思路:
不建树,顺着父节点,向上搜索,同时累加路径上的通知时间
-
实现:dfs+记忆化
class Solution { public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { var memo = new int[n]; Arrays.fill(memo, -1); // -1 表示还没有计算过 int ans = 0; for (int i = 0; i < n; i++) ans = Math.max(ans, dfs(manager, informTime, memo, i)); return ans; } private int dfs(int[] manager, int[] informTime, int[] memo, int x) { if (manager[x] < 0) return informTime[x]; if (memo[x] >= 0) return memo[x]; // 之前计算过了 return memo[x] = dfs(manager, informTime, memo, manager[x]) + informTime[x]; } } 作者:灵茶山艾府 链接:https://leetcode.cn/problems/time-needed-to-inform-all-employees/solutions/2251986/shen-ru-li-jie-di-gui-zi-ding-xiang-xia-ps0mm/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
-
优化:标记为-1
class Solution { public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { int ans = 0; for (int i = 0; i < n; i++) ans = Math.max(ans, dfs(manager, informTime, i)); return ans; } private int dfs(int[] manager, int[] informTime, int x) { if (manager[x] >= 0) { informTime[x] += dfs(manager, informTime, manager[x]); manager[x] = -1; // 标记 x 计算过 } return informTime[x]; } } 作者:灵茶山艾府 链接:https://leetcode.cn/problems/time-needed-to-inform-all-employees/solutions/2251986/shen-ru-li-jie-di-gui-zi-ding-xiang-xia-ps0mm/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。