Skip to content

Commit 4112a29

Browse files
committed
+ problem 2050
1 parent fcec556 commit 4112a29

File tree

5 files changed

+222
-0
lines changed

5 files changed

+222
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# 2050. Parallel Courses III
2+
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 <code>relations[j] = [prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> denotes that course <code>prevCourse<sub>j</sub></code> has to be completed before course <code>nextCourse<sub>j</sub></code> (prerequisite relationship). Furthermore, you are given a 0-indexed integer array `time` where `time[i]` denotes how many months it takes to complete the <code>(i+1)<sup>th</sup></code> course.
3+
4+
You must find the **minimum** number of months needed to complete all the courses following these rules:
5+
* You may start taking a course at **any time** if the prerequisites are met.
6+
* **Any number of courses** can be taken at the **same time**.
7+
8+
Return *the **minimum** number of months needed to complete all the courses*.
9+
10+
**Note:** The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).
11+
12+
#### Example 1:
13+
![](https://assets.leetcode.com/uploads/2021/10/07/ex1.png)
14+
<pre>
15+
<strong>Input:</strong> n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
16+
<strong>Output:</strong> 8
17+
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
18+
We start course 1 and course 2 simultaneously at month 0.
19+
Course 1 takes 3 months and course 2 takes 2 months to complete respectively.
20+
Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.
21+
</pre>
22+
23+
#### Example 2:
24+
![](https://assets.leetcode.com/uploads/2021/10/07/ex2.png)
25+
<pre>
26+
<strong>Input:</strong> n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5]
27+
<strong>Output:</strong> 12
28+
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
29+
You can start courses 1, 2, and 3 at month 0.
30+
You can complete them after 1, 2, and 3 months respectively.
31+
Course 4 can be taken only after course 3 is completed, i.e., after 3 months. It is completed after 3 + 4 = 7 months.
32+
Course 5 can be taken only after courses 1, 2, 3, and 4 have been completed, i.e., after max(1,2,3,7) = 7 months.
33+
Thus, the minimum time needed to complete all the courses is 7 + 5 = 12 months.
34+
</pre>
35+
36+
#### Constraints:
37+
* <code>1 <= n <= 5 * 10<sup>4</sup></code>
38+
* <code>0 <= relations.length <= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code>
39+
* `relations[j].length == 2`
40+
* <code>1 <= prevCourse<sub>j</sub>, nextCourse<sub>j</sub> <= n</code>
41+
* <code>prevCourse<sub>j</sub> != nextCourse<sub>j</sub></code>
42+
* All the pairs <code>[prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> are **unique**.
43+
* `time.length == n`
44+
* <code>1 <= time[i] <= 10<sup>4</sup></code>
45+
* The given graph is a directed acyclic graph.
46+
47+
## Solutions (Rust)
48+
49+
### 1. Solution
50+
```Rust
51+
impl Solution {
52+
pub fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
53+
let mut next_courses = vec![vec![]; n as usize];
54+
let mut indgree = vec![0; n as usize];
55+
let mut start = vec![0; n as usize];
56+
let mut stack = vec![];
57+
let mut ret = 0;
58+
59+
for relation in &relations {
60+
let (prev, next) = (relation[0] as usize - 1, relation[1] as usize - 1);
61+
62+
next_courses[prev].push(next);
63+
indgree[next] += 1;
64+
}
65+
66+
for i in 0..n as usize {
67+
if indgree[i] == 0 {
68+
stack.push(i);
69+
}
70+
}
71+
72+
while let Some(prev) = stack.pop() {
73+
let end = start[prev] + time[prev];
74+
75+
for &next in &next_courses[prev] {
76+
indgree[next] -= 1;
77+
start[next] = start[next].max(end);
78+
if indgree[next] == 0 {
79+
stack.push(next);
80+
}
81+
}
82+
83+
ret = ret.max(end);
84+
}
85+
86+
ret
87+
}
88+
}
89+
```
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# 2050. 并行课程 III
2+
给你一个整数 `n` ,表示有 `n` 节课,课程编号从 `1``n` 。同时给你一个二维整数数组 `relations` ,其中 <code>relations[j] = [prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> ,表示课程 <code>prevCourse<sub>j</sub></code> 必须在课程 <code>nextCourse<sub>j</sub></code> 之前 完成(先修课的关系)。同时给你一个下标从 **0** 开始的整数数组 `time` ,其中 `time[i]` 表示完成第 `(i+1)` 门课程需要花费的 **月份** 数。
3+
4+
请你根据以下规则算出完成所有课程所需要的 **最少** 月份数:
5+
* 如果一门课的所有先修课都已经完成,你可以在 **任意** 时间开始这门课程。
6+
* 你可以 **同时****任意门课程**
7+
8+
请你返回完成所有课程所需要的 **最少** 月份数。
9+
10+
**注意:**测试数据保证一定可以完成所有课程(也就是先修课的关系构成一个有向无环图)。
11+
12+
#### 示例 1:
13+
![](https://assets.leetcode.com/uploads/2021/10/07/ex1.png)
14+
<pre>
15+
<strong>输入:</strong> n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
16+
<strong>输出:</strong> 8
17+
<strong>解释:</strong> 上图展示了输入数据所表示的先修关系图,以及完成每门课程需要花费的时间。
18+
你可以在月份 0 同时开始课程 1 和 2 。
19+
课程 1 花费 3 个月,课程 2 花费 2 个月。
20+
所以,最早开始课程 3 的时间是月份 3 ,完成所有课程所需时间为 3 + 5 = 8 个月。
21+
</pre>
22+
23+
#### 示例 2:
24+
![](https://assets.leetcode.com/uploads/2021/10/07/ex2.png)
25+
<pre>
26+
<strong>输入:</strong> n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5]
27+
<strong>输出:</strong> 12
28+
<strong>解释:</strong> 上图展示了输入数据所表示的先修关系图,以及完成每门课程需要花费的时间。
29+
你可以在月份 0 同时开始课程 1 ,2 和 3 。
30+
在月份 1,2 和 3 分别完成这三门课程。
31+
课程 4 需在课程 3 之后开始,也就是 3 个月后。课程 4 在 3 + 4 = 7 月完成。
32+
课程 5 需在课程 1,2,3 和 4 之后开始,也就是在 max(1,2,3,7) = 7 月开始。
33+
所以完成所有课程所需的最少时间为 7 + 5 = 12 个月。
34+
</pre>
35+
36+
#### 提示:
37+
* <code>1 <= n <= 5 * 10<sup>4</sup></code>
38+
* <code>0 <= relations.length <= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code>
39+
* `relations[j].length == 2`
40+
* <code>1 <= prevCourse<sub>j</sub>, nextCourse<sub>j</sub> <= n</code>
41+
* <code>prevCourse<sub>j</sub> != nextCourse<sub>j</sub></code>
42+
* 所有的先修课程对 <code>[prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code> 都是 **互不相同** 的。
43+
* `time.length == n`
44+
* <code>1 <= time[i] <= 10<sup>4</sup></code>
45+
* 先修课程图是一个有向无环图。
46+
47+
## 题解 (Rust)
48+
49+
### 1. 题解
50+
```Rust
51+
impl Solution {
52+
pub fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
53+
let mut next_courses = vec![vec![]; n as usize];
54+
let mut indgree = vec![0; n as usize];
55+
let mut start = vec![0; n as usize];
56+
let mut stack = vec![];
57+
let mut ret = 0;
58+
59+
for relation in &relations {
60+
let (prev, next) = (relation[0] as usize - 1, relation[1] as usize - 1);
61+
62+
next_courses[prev].push(next);
63+
indgree[next] += 1;
64+
}
65+
66+
for i in 0..n as usize {
67+
if indgree[i] == 0 {
68+
stack.push(i);
69+
}
70+
}
71+
72+
while let Some(prev) = stack.pop() {
73+
let end = start[prev] + time[prev];
74+
75+
for &next in &next_courses[prev] {
76+
indgree[next] -= 1;
77+
start[next] = start[next].max(end);
78+
if indgree[next] == 0 {
79+
stack.push(next);
80+
}
81+
}
82+
83+
ret = ret.max(end);
84+
}
85+
86+
ret
87+
}
88+
}
89+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
impl Solution {
2+
pub fn minimum_time(n: i32, relations: Vec<Vec<i32>>, time: Vec<i32>) -> i32 {
3+
let mut next_courses = vec![vec![]; n as usize];
4+
let mut indgree = vec![0; n as usize];
5+
let mut start = vec![0; n as usize];
6+
let mut stack = vec![];
7+
let mut ret = 0;
8+
9+
for relation in &relations {
10+
let (prev, next) = (relation[0] as usize - 1, relation[1] as usize - 1);
11+
12+
next_courses[prev].push(next);
13+
indgree[next] += 1;
14+
}
15+
16+
for i in 0..n as usize {
17+
if indgree[i] == 0 {
18+
stack.push(i);
19+
}
20+
}
21+
22+
while let Some(prev) = stack.pop() {
23+
let end = start[prev] + time[prev];
24+
25+
for &next in &next_courses[prev] {
26+
indgree[next] -= 1;
27+
start[next] = start[next].max(end);
28+
if indgree[next] == 0 {
29+
stack.push(next);
30+
}
31+
}
32+
33+
ret = ret.max(end);
34+
}
35+
36+
ret
37+
}
38+
}

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@
12881288
[2047][2047l]|[Number of Valid Words in a Sentence][2047] |![py]
12891289
[2048][2048l]|[Next Greater Numerically Balanced Number][2048] |![rs]
12901290
[2049][2049l]|[Count Nodes With the Highest Score][2049] |![rs]
1291+
[2050][2050l]|[Parallel Courses III][2050] |![rs]
12911292
[2053][2053l]|[Kth Distinct String in an Array][2053] |![py]
12921293
[2054][2054l]|[Two Best Non-Overlapping Events][2054] |![rs]
12931294
[2055][2055l]|[Plates Between Candles][2055] |![rs]
@@ -2911,6 +2912,7 @@
29112912
[2047]:Problemset/2047-Number%20of%20Valid%20Words%20in%20a%20Sentence/README.md#2047-number-of-valid-words-in-a-sentence
29122913
[2048]:Problemset/2048-Next%20Greater%20Numerically%20Balanced%20Number/README.md#2048-next-greater-numerically-balanced-number
29132914
[2049]:Problemset/2049-Count%20Nodes%20With%20the%20Highest%20Score/README.md#2049-count-nodes-with-the-highest-score
2915+
[2050]:Problemset/2050-Parallel%20Courses%20III/README.md#2050-parallel-courses-iii
29142916
[2053]:Problemset/2053-Kth%20Distinct%20String%20in%20an%20Array/README.md#2053-kth-distinct-string-in-an-array
29152917
[2054]:Problemset/2054-Two%20Best%20Non-Overlapping%20Events/README.md#2054-two-best-non-overlapping-events
29162918
[2055]:Problemset/2055-Plates%20Between%20Candles/README.md#2055-plates-between-candles
@@ -4528,6 +4530,7 @@
45284530
[2047l]:https://leetcode.com/problems/number-of-valid-words-in-a-sentence/
45294531
[2048l]:https://leetcode.com/problems/next-greater-numerically-balanced-number/
45304532
[2049l]:https://leetcode.com/problems/count-nodes-with-the-highest-score/
4533+
[2050l]:https://leetcode.com/problems/parallel-courses-iii/
45314534
[2053l]:https://leetcode.com/problems/kth-distinct-string-in-an-array/
45324535
[2054l]:https://leetcode.com/problems/two-best-non-overlapping-events/
45334536
[2055l]:https://leetcode.com/problems/plates-between-candles/

README_CN.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@
12881288
[2047][2047l]|[句子中的有效单词数][2047] |![py]
12891289
[2048][2048l]|[下一个更大的数值平衡数][2048] |![rs]
12901290
[2049][2049l]|[统计最高分的节点数目][2049] |![rs]
1291+
[2050][2050l]|[并行课程 III][2050] |![rs]
12911292
[2053][2053l]|[数组中第 K 个独一无二的字符串][2053] |![py]
12921293
[2054][2054l]|[两个最好的不重叠活动][2054] |![rs]
12931294
[2055][2055l]|[蜡烛之间的盘子][2055] |![rs]
@@ -2911,6 +2912,7 @@
29112912
[2047]:Problemset/2047-Number%20of%20Valid%20Words%20in%20a%20Sentence/README_CN.md#2047-句子中的有效单词数
29122913
[2048]:Problemset/2048-Next%20Greater%20Numerically%20Balanced%20Number/README_CN.md#2048-下一个更大的数值平衡数
29132914
[2049]:Problemset/2049-Count%20Nodes%20With%20the%20Highest%20Score/README_CN.md#2049-统计最高分的节点数目
2915+
[2050]:Problemset/2050-Parallel%20Courses%20III/README_CN.md#2050-并行课程-iii
29142916
[2053]:Problemset/2053-Kth%20Distinct%20String%20in%20an%20Array/README_CN.md#2053-数组中第-k-个独一无二的字符串
29152917
[2054]:Problemset/2054-Two%20Best%20Non-Overlapping%20Events/README_CN.md#2054-两个最好的不重叠活动
29162918
[2055]:Problemset/2055-Plates%20Between%20Candles/README_CN.md#2055-蜡烛之间的盘子
@@ -4528,6 +4530,7 @@
45284530
[2047l]:https://leetcode.cn/problems/number-of-valid-words-in-a-sentence/
45294531
[2048l]:https://leetcode.cn/problems/next-greater-numerically-balanced-number/
45304532
[2049l]:https://leetcode.cn/problems/count-nodes-with-the-highest-score/
4533+
[2050l]:https://leetcode.cn/problems/parallel-courses-iii/
45314534
[2053l]:https://leetcode.cn/problems/kth-distinct-string-in-an-array/
45324535
[2054l]:https://leetcode.cn/problems/two-best-non-overlapping-events/
45334536
[2055l]:https://leetcode.cn/problems/plates-between-candles/

0 commit comments

Comments
 (0)