【图论】B033_LC_通知所有员工所需的时间(自底向上 / 自顶向下)

一、Problem

A company has n employees with a unique ID for each employee from 0 to n - 1. The head of the company has is the one with headID.

Each employee has one direct manager given in the manager array where manager[i] is the direct manager of the i-th employee, manager[headID] = -1. Also it’s guaranteed that the subordination relationships have a tree structure.

The head of the company wants to inform all the employees of the company of an urgent piece of news. He will inform his direct subordinates and they will inform their subordinates and so on until all employees know about the urgent news.

The i-th employee needs informTime[i] minutes to inform all of his direct subordinates (i.e After informTime[i] minutes, all his direct subordinates can start spreading the news).

Return the number of minutes needed to inform all the employees about the urgent news.

在这里插入图片描述
Constraints:

1 <= n <= 10^5
0 <= headID < n
manager.length == n
0 <= manager[i] < n
manager[headID] == -1
informTime.length == n
0 <= informTime[i] <= 1000
informTime[i] == 0 if employee i has no subordinates.
It is guaranteed that all the employees can be informed.

二、Solution

方法一:暴力枚举

  • 从每一个叶子结点往上遍历到 hID,累加其中的通知时间。
  • 取从每个结点开始的最大值。

这种想法是逆向的,比赛的时候如果不冷静就没办法立刻想到,最普通的做法就是用邻接表将有向树的结点和边存一下,然后从 headID 遍历一下树,当到达叶子结点时,比较最大通知时间。

757 ms,勉强能过,看能不能优化一下…

class Solution {
    public int numOfMinutes(int n, int hID, int[] mng, int[] info) {
        int max = 0;
        for (int i = 0; i < n; i++) {
            int cur = 0, t = i;
            while (mng[t] != -1) {
                t = mng[t];
                cur += info[t];
            }
            max = Math.max(max, cur);
        }
        return max;
    }
}
  • 因为遍历是从下往上进行的,所以从第一次遍历图中已经经过的结点再次遍历,得到的累加和一定是小于从这个第一次开始遍历的结点的。
  • 所以我们可以用 boolean[] vis 记录一下结点的状态。
class Solution {
    public int numOfMinutes(int n, int hID, int[] mng, int[] info) {
        int max = 0;
        boolean[] vis = new boolean[n];
        for (int i = 0; i < n; i++) {
            int cur = 0, t = i;
            if (vis[t])
                continue;
            while (mng[t] != -1) {
                vis[t] = true;
                t = mng[t];
                cur += info[t];
            }
            max = Math.max(max, cur);
        }
        return max;
    }
}

优化之后,变为W了 491 ms,有效果,还行…

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章