【圖論】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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章