You are given an integer n
, which indicates that there are n
courses labeled from 1
to n
. You are also given a 2D integer array relations
where relations[j] = [prevCoursej, nextCoursej]
denotes that course prevCoursej
has to be completed before course nextCoursej
(prerequisite relationship). Furthermore, you are given a 0-indexed integer array time
where time[i]
denotes how many months it takes to complete the (i+1)th
course.
You must find the minimum number of months needed to complete all the courses following these rules:
- You may start taking a course at any time if the prerequisites are met.
- Any number of courses can be taken at the same time.
Return the minimum number of months needed to complete all the courses.
Note: The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).
Example 1:
Input: n = 3, relations = [[1,3],[2,3]], time = [3,2,5] Output: 8 Explanation: The figure above represents the given graph and the time required to complete each course. We start course 1 and course 2 simultaneously at month 0. Course 1 takes 3 months and course 2 takes 2 months to complete respectively. Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.
思路:就是个topo排序,注意的点:
1. 给的relationship是index +1的,所以为了方便,build graph的时候,直接减去1,这样和后面的time也 一一对应;
2. 核心的算法就是用topo更新每个点index,需要花的时间,最后求个最大的即可。
3. 计算neighbor的时间,finishTime[neighbor] = finishTime[node] + time[neighbor]; 因为node poll出来就是入度为0点,那么就应该用finishTime来计算;
class Solution {
public int minimumTime(int n, int[][] relations, int[] time) {
int[] finishTime = new int[n];
int[] indegree = new int[n];
HashMap<Integer, List<Integer>> graph = new HashMap<>();
for(int i = 0; i < n; i++) {
graph.putIfAbsent(i, new ArrayList<>());
}
for(int[] relation: relations) {
// a -> b;
int a = relation[0] - 1;
int b = relation[1] - 1;
graph.get(a).add(b);
indegree[b]++;
}
Queue<Integer> queue = new LinkedList<>();
for(int i = 0; i < n; i++) {
if(indegree[i] == 0) {
finishTime[i] = time[i];
queue.offer(i);
}
}
while(!queue.isEmpty()) {
Integer node = queue.poll();
for(Integer neighbor: graph.get(node)) {
// 注意这里,因为node 已经poll出来了,所以计算的时候是用的finishTime[node] + time[neighbor];
finishTime[neighbor] = Math.max(finishTime[neighbor], finishTime[node] + time[neighbor]);
indegree[neighbor]--;
if(indegree[neighbor] == 0) {
queue.offer(neighbor);
}
}
}
int res = 0;
for(int i = 0; i < n; i++) {
res = Math.max(res, finishTime[i]);
}
return res;
}
}