Skip to content

Commit 434f6ed

Browse files
committed
三刷207
1 parent 4ad7765 commit 434f6ed

File tree

4 files changed

+90
-65
lines changed

4 files changed

+90
-65
lines changed

Diff for: docs/0000-19-topological-sort.adoc

+11-37
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
[#0000-19-topological-sort]
22
= Topological Sort (Graph) 拓扑排序
33

4-
拓扑排序模式用来寻找一种线性的顺序,这些元素之间具有依懒性。比如,如果事件B依赖于事件A,那A在拓扑排序顺序中排在B的前面
4+
拓扑排序模式用来寻找一种线性的顺序,这些元素之间具有依懒性。比如,如果事件 B 依赖于事件 A,那 A 在拓扑排序顺序中排在 B 的前面
55

66
这种模式定义了一种简单方式来理解拓扑排序这种技术。
77

88
这种模式是这样奏效的:
99

1010
. 初始化
11-
.. 借助于HashMap将图保存成邻接表形式
12-
.. 找到所有的起点,用HashMap来帮助记录每个节点的入度
11+
.. 借助于 `Map` 将图保存成邻接表形式
12+
.. 找到所有的起点,`Map` 来帮助记录每个节点的入度
1313
. 创建图,找到每个节点的入度
14-
.. 利用输入,把图建好,然后遍历一下图,将入度信息记录在HashMap中
14+
.. 利用输入,把图建好,然后遍历一下图,将入度信息记录在 `Map`
1515
. 找所有的起点
16-
.. 所有入度为0的节点,都是有效的起点,而且我们讲他们都加入到一个队列中
16+
.. 所有入度为 `0` 的节点,都是有效的起点,而且我们讲他们都加入到一个队列中
1717
. 排序
1818
.. 对每个起点,执行以下步骤
1919
... 把它加到结果的顺序中
2020
... 将其在图中的孩子节点取到
2121
... 将其孩子的入度减少1
2222
... 如果孩子的入度变为0,则改孩子节点成为起点,将其加入队列中
23-
.. 重复(a)过程,直到起点队列为空。
23+
.. 重复上述过程,直到起点队列为空。
24+
25+
用一句话概括:将依赖关系转化成一张有向图,如果这张图中的节点没有循环依赖,那么则方案可行,否则方案不可行。
26+
27+
TIP: 这里解释的是一种广度优先搜索,看 https://leetcode.cn/problems/course-schedule/solutions/359392/ke-cheng-biao-by-leetcode-solution/[207. 课程表 - 官方题解^],还存在一种深度优先搜索的处理办法,有机会尝试一下。
2428

2529
拓扑排序模式识别:
2630

@@ -33,38 +37,8 @@
3337
. xref:0207-course-schedule.adoc[207. Course Schedule]
3438
. xref:0210-course-schedule-ii.adoc[210. Course Schedule II]
3539
. xref:0269-alien-dictionary.adoc[269. Alien Dictionary]
36-
. xref:0310-minimum-height-trees.adoc[310. Minimum Height Trees]
37-
. xref:0329-longest-increasing-path-in-a-matrix.adoc[329. Longest Increasing Path in a Matrix]
3840
. xref:0444-sequence-reconstruction.adoc[444. Sequence Reconstruction]
39-
. xref:0631-design-excel-sum-formula.adoc[631. Design Excel Sum Formula]
40-
. xref:0802-find-eventual-safe-states.adoc[802. Find Eventual Safe States]
41-
. xref:0851-loud-and-rich.adoc[851. Loud and Rich]
42-
. xref:0913-cat-and-mouse.adoc[913. Cat and Mouse]
43-
. xref:1059-all-paths-from-source-lead-to-destination.adoc[1059. All Paths from Source Lead to Destination]
44-
. xref:1136-parallel-courses.adoc[1136. Parallel Courses]
45-
. xref:1203-sort-items-by-groups-respecting-dependencies.adoc[1203. Sort Items by Groups Respecting Dependencies]
46-
. xref:1245-tree-diameter.adoc[1245. Tree Diameter]
47-
. xref:1462-course-schedule-iv.adoc[1462. Course Schedule IV]
48-
. xref:1591-strange-printer-ii.adoc[1591. Strange Printer II]
49-
. xref:1632-rank-transform-of-a-matrix.adoc[1632. Rank Transform of a Matrix]
50-
. xref:1728-cat-and-mouse-ii.adoc[1728. Cat and Mouse II]
51-
. xref:1786-number-of-restricted-paths-from-first-to-last-node.adoc[1786. Number of Restricted Paths From First to Last Node]
52-
. xref:1857-largest-color-value-in-a-directed-graph.adoc[1857. Largest Color Value in a Directed Graph]
53-
. xref:1916-count-ways-to-build-rooms-in-an-ant-colony.adoc[1916. Count Ways to Build Rooms in an Ant Colony]
54-
. xref:1976-number-of-ways-to-arrive-at-destination.adoc[1976. Number of Ways to Arrive at Destination]
55-
. xref:2050-parallel-courses-iii.adoc[2050. Parallel Courses III]
56-
. xref:2115-find-all-possible-recipes-from-given-supplies.adoc[2115. Find All Possible Recipes from Given Supplies]
57-
. xref:2127-maximum-employees-to-be-invited-to-a-meeting.adoc[2127. Maximum Employees to Be Invited to a Meeting]
58-
. xref:2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph.adoc[2192. All Ancestors of a Node in a Directed Acyclic Graph]
59-
. xref:2246-longest-path-with-different-adjacent-characters.adoc[2246. Longest Path With Different Adjacent Characters]
60-
. xref:2328-number-of-increasing-paths-in-a-grid.adoc[2328. Number of Increasing Paths in a Grid]
61-
. xref:2360-longest-cycle-in-a-graph.adoc[2360. Longest Cycle in a Graph]
62-
. xref:2371-minimize-maximum-value-in-a-grid.adoc[2371. Minimize Maximum Value in a Grid]
63-
. xref:2392-build-a-matrix-with-conditions.adoc[2392. Build a Matrix With Conditions]
64-
. xref:2603-collect-coins-in-a-tree.adoc[2603. Collect Coins in a Tree]
65-
. xref:3383-minimum-runes-to-add-to-cast-spell.adoc[3383. Minimum Runes to Add to Cast Spell]
66-
. xref:3435-frequencies-of-shortest-supersequences.adoc[3435. Frequencies of Shortest Supersequences]
67-
. xref:3481-apply-substitutions.adoc[3481. Apply Substitutions]
41+
. xref:0310-minimum-height-trees.adoc[310. Minimum Height Trees]
6842

6943
== 参考资料
7044

Diff for: docs/0207-course-schedule.adoc

+34-28
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,42 @@
11
[#0207-course-schedule]
2-
= 207. Course Schedule
2+
= 207. 课程表
33

4-
{leetcode}/problems/course-schedule/[LeetCode - Course Schedule^]
4+
https://leetcode.cn/problems/course-schedule/[LeetCode - 207. 课程表 ^]
55

6-
There are a total of _n_ courses you have to take, labeled from `0` to `n-1`.
6+
你这个学期必须选修 `numCourses` 门课程,记为 `0` `numCourses - 1`
77

8-
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: `[0,1]`
8+
在选修某些课程之前需要一些先修课程。 先修课程按数组 `prerequisites` 给出,其中 `prerequisites[i] = [a~i~, b~i~]`,表示如果要学习课程 `a~i~`*必须* 先学习课程 `b~i~`
99

10-
Given the total number of courses and a list of prerequisite *pairs*, is it possible for you to finish all courses?
10+
* 例如,先修课程对 `[0, 1]` 表示:想要学习课程 `0`,你需要先完成课程 `1`
1111
12-
*Example 1:*
12+
请你判断是否可能完成所有课程的学习?如果可以,返回 `true` ;否则,返回 `false`
1313

14-
[subs="verbatim,quotes,macros"]
15-
----
16-
*Input:* 2, [[1,0]]
17-
*Output:* true
18-
*Explanation:* There are a total of 2 courses to take.
19-
To take course 1 you should have finished course 0. So it is possible.
20-
----
14+
*示例 1:*
2115

22-
*Example 2:*
16+
....
17+
输入:numCourses = 2, prerequisites = [[1,0]]
18+
输出:true
19+
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
20+
....
2321

24-
[subs="verbatim,quotes,macros"]
25-
----
26-
*Input:* 2, [[1,0],[0,1]]
27-
*Output:* false
28-
*Explanation:* There are a total of 2 courses to take.
29-
To take course 1 you should have finished course 0, and to take course 0 you should
30-
also have finished course 1. So it is impossible.
22+
*示例 2:*
3123

32-
----
24+
....
25+
输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
26+
输出:false
27+
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
28+
....
3329

34-
*Note:*
30+
*提示:*
3531

36-
37-
. The input prerequisites is a graph represented by *a list of edges*, not adjacency matrices. Read more about https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs[how a graph is represented^].
38-
. You may assume that there are no duplicate edges in the input prerequisites.
32+
* `+1 <= numCourses <= 2000+`
33+
* `+0 <= prerequisites.length <= 5000+`
34+
* `prerequisites[i].length == 2`
35+
* `0 \<= a~i~, b~i~ < numCourses`
36+
* `prerequisites[i]` 中的所有课程对 *互不相同*
3937
4038
== 思路分析
4139

42-
4340
TODO: 研究一下图相关算法和拓扑排序。
4441

4542
拓扑排序通常用来“排序”具有依赖关系的任务。
@@ -66,6 +63,15 @@ include::{sourcedir}/_0207_CourseSchedule.java[tag=answer]
6663
include::{sourcedir}/_0207_CourseSchedule_2.java[tag=answer]
6764
----
6865
--
66+
67+
三刷::
68+
+
69+
--
70+
[{java_src_attr}]
71+
----
72+
include::{sourcedir}/_0207_CourseSchedule_3.java[tag=answer]
73+
----
74+
--
6975
====
7076

7177

@@ -77,6 +83,6 @@ include::{sourcedir}/_0207_CourseSchedule_2.java[tag=answer]
7783
. https://www.cnblogs.com/bigsai/p/11489260.html[拓扑排序详解与实现^]
7884
. https://jingsam.github.io/2020/08/11/topological-sort.html[拓扑排序原理^]
7985
. https://leetcode.cn/problems/course-schedule/solutions/18806/course-schedule-tuo-bu-pai-xu-bfsdfsliang-chong-fa/?envType=study-plan-v2&envId=selected-coding-interview[207. 课程表 - 拓扑排序:入度表BFS法 / DFS法,清晰图解^]
80-
. https://leetcode.cn/problems/course-schedule/solutions/359392/ke-cheng-biao-by-leetcode-solution/?envType=study-plan-v2&envId=selected-coding-interview[207. 课程表 - 官方题解^]
86+
. https://leetcode.cn/problems/course-schedule/solutions/359392/ke-cheng-biao-by-leetcode-solution/[207. 课程表 - 官方题解^]
8187
. https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs[Representing graphs (article) | Algorithms | Khan Academy^]
8288

Diff for: logbook/202503.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ endif::[]
140140
|{doc_base_url}/0015-3sum.adoc[题解]
141141
|✅ 利用递归“降维”
142142

143+
|{counter:codes2503}
144+
|{leetcode_base_url}/course-schedule/[207. Course Schedule^]
145+
|{doc_base_url}/0207-course-schedule.adoc[题解]
146+
|✅ 拓扑排序
147+
143148
|===
144149

145150
截止目前,本轮练习一共完成 {codes2503} 道题。
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.*;
4+
5+
public class _0207_CourseSchedule_3 {
6+
// tag::answer[]
7+
/**
8+
* @author D瓜哥 · https://www.diguage.com
9+
* @since 2025-04-04 09:09:52
10+
*/
11+
public boolean canFinish(int numCourses, int[][] prerequisites) {
12+
Map<Integer, List<Integer>> graph = new HashMap<>();
13+
int[] indegree = new int[numCourses];
14+
for (int[] p : prerequisites) {
15+
List<Integer> children = graph.computeIfAbsent(p[0], k -> new ArrayList<>());
16+
children.add(p[1]);
17+
indegree[p[1]]++;
18+
}
19+
Queue<Integer> queue = new LinkedList<>();
20+
for (int i = 0; i < indegree.length; i++) {
21+
if (indegree[i] == 0) {
22+
queue.offer(i);
23+
}
24+
}
25+
int cnt = 0;
26+
while (!queue.isEmpty()) {
27+
Integer c = queue.poll();
28+
cnt++;
29+
List<Integer> children = graph.getOrDefault(c, Collections.emptyList());
30+
for (Integer child : children) {
31+
indegree[child]--;
32+
if (indegree[child] == 0) {
33+
queue.offer(child);
34+
}
35+
}
36+
}
37+
return cnt == numCourses;
38+
}
39+
// end::answer[]
40+
}

0 commit comments

Comments
 (0)