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; }