1376. 通知所有员工所需的时间

题目:

思路:

【1】广度优先遍历

假设输入为:
int n = 11, headID = 4;
int[] manager = new int[]{5,9,6,10,-1,8,9,1,9,3,4},
informTime = new int[]{0,213,0,253,686,170,975,0,261,309,337};

那么其实构建的树为
        686
         |
        337
         |
        253
         |
        309
    /     |    \
   213   975   261
    |     |     |
    0     0    170
                |
                0
故可以看做查找从根节点到叶子节点的路径最大值:
所以使用层次遍历的方式是不可取的,使用广度也是很吃力的

 

【2】深度优先遍历

【3】记忆化搜索(优化)

代码展示:

【1】深度优先遍历

//时间100 ms 击败 23.33%
//内存58.2 MB 击败 69.80%
//时间复杂度:O(n)。
//空间复杂度:O(n),主要为建图的空间开销。
class Solution {
    public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
        HashMap<Integer,ArrayList<Integer>> timeMap = new HashMap<>();
        for (int i = 0; i < manager.length; i++){
            ArrayList<Integer> temp = timeMap.getOrDefault(manager[i],new ArrayList<Integer>());
            temp.add(i);
            timeMap.put(manager[i],temp);
        }
        int time = informTime[headID];
        time += nextMaxTime(headID,timeMap,informTime);
        return time;
    }

    public int nextMaxTime(int headID, HashMap<Integer,ArrayList<Integer>> timeMap, int[] informTime) {
        ArrayList<Integer> list = timeMap.getOrDefault(headID,new ArrayList<Integer>());
        int maxTime = 0;
        for (Integer t : list){
            int curTime = informTime[t];
            curTime += nextMaxTime(t,timeMap,informTime);
            maxTime = Math.max(curTime,maxTime);
        }
        return maxTime;
    }
}

 

【2】记忆化搜索(如何实现自底向上的方式)

//时间69 ms 击败 59.39%
//内存53.8 MB 击败 98.1%
//时间复杂度:O(n)。
//空间复杂度:O(n),主要为对记忆化的空间开销。
class Solution {
    int headID;  // 公司总负责人 ID
    int[] manager;  // manager[i] 表示第 i 名员工的直属负责人
    int[] informTime;  // informTime[i] 表示第 i 名员工通知直属下属所需时间
    Map<Integer, Integer> memo = new HashMap<Integer, Integer>();  // 记忆化搜索缓存

    public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
        this.headID = headID;
        this.manager = manager;
        this.informTime = informTime;
        int res = 0;  // 记录最长时间
        for (int i = 0; i < n; i++) {
            res = Math.max(res, dfs(i));  // 对每个员工遍历,更新最长时间
        }
        return res;
    }

    public int dfs(int cur) {
        if (cur == headID) {  // 当前节点为根节点
            return 0;
        }
        if (!memo.containsKey(cur)) {  // 检查缓存中是否已经存在当前节点的时间
            int res = dfs(manager[cur]) + informTime[manager[cur]];  // 递归遍历当前节点的直属上级节点,返回时间和
            memo.put(cur, res);  // 将当前节点到根节点的时间加入缓存中
        }
        return memo.get(cur);  // 返回当前节点到根节点的时间
    }
}


//时间13 ms击败87.62%
//内存55.5 MB 击败 81.48%
class Solution {
    public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
        ans = Integer.MIN_VALUE;
        this.headID = headID;
        this.manager = manager;
        this.informTime = informTime;
        db = new int[n];
        Arrays.fill(db, -1);
        for (int i = 0; i < n; ++i) {
            if (db[i] == -1) {
                dfs(i);
            }
            ans = Math.max(ans, db[i]);
        }
        return ans;
    }

    public int dfs(int emp) {
        if (db[emp] != -1) return db[emp];
        if (emp == headID) {
            db[emp] = 0;
        } else {
            int boss = manager[emp];
            db[emp] = informTime[boss] + dfs(boss);
        }

        return db[emp];
    }
    int ans;
    int[] db;
    int headID;
    int[] manager;
    int[] informTime;
}

 

posted @ 2023-07-24 12:13  忧愁的chafry  阅读(18)  评论(0编辑  收藏  举报