【每日一题Day193】LC1376通知所有员工所需的时间 | dfs

简介: 【每日一题Day193】LC1376通知所有员工所需的时间 | dfs

通知所有员工所需的时间【LC1376】

公司里有 n 名员工,每个员工的 ID 都是独一无二的,编号从 0n - 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];
    }
}

image.png

自底向上

  • 思路:
    不建树,顺着父节点,向上搜索,同时累加路径上的通知时间
  • 实现: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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


目录
相关文章
|
2天前
|
JavaScript 测试技术
【动态规划】【精度】1883. 准时抵达会议现场的最小跳过休息次数
【动态规划】【精度】1883. 准时抵达会议现场的最小跳过休息次数
|
2天前
【每日一题Day365】LC2172参加会议的最多员工数 | 拓扑排序
【每日一题Day365】LC2172参加会议的最多员工数 | 拓扑排序
39 1
|
2天前
【每日一题Day258】LC2532过桥的时间 | 模拟 优先队列
【每日一题Day258】LC2532过桥的时间 | 模拟 优先队列
27 0
|
2天前
【每日一题Day305】LC1448统计二叉树中好节点的数目 | dfs
【每日一题Day305】LC1448统计二叉树中好节点的数目 | dfs
23 0
|
2天前
【每日一题Day356】LC2678老人的数目 | 字符串
【每日一题Day356】LC2678老人的数目 | 字符串
25 0
|
2天前
|
存储
【每日一题Day123】LC1792最大平均通过率 | 堆
【每日一题Day123】LC1792最大平均通过率 | 堆
29 0
|
2天前
【每日一题Day197】LC2432处理用时最长的那个任务的员工 | 枚举
【每日一题Day197】LC2432处理用时最长的那个任务的员工 | 枚举
29 0
|
2天前
【每日一题Day180】LC2409统计共同度过的日子数 | 模拟
【每日一题Day180】LC2409统计共同度过的日子数 | 模拟
21 0
|
2天前
【每日一题Day209】LC2446判断两个事件是否存在冲突
【每日一题Day209】LC2446判断两个事件是否存在冲突
22 0
|
2天前
【每日一题Day164】LC831隐藏个人信息 | 模拟
【每日一题Day164】LC831隐藏个人信息 | 模拟
22 0