NOTE
课程表
课程表问题:DFS 与 BFS 拓扑排序。
这是历史学习笔记,可能存在过时或不完整的理解。
1. 题目描述
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
2. 思路
- DFS
- BFS-拓扑排序
3. 实现
3.1. DFS
package main
func canFinish(numCourses int, prerequisites [][]int) bool {
graph := make([][]int, numCourses)
for i := 0; i < len(graph); i++ {
graph[i] = make([]int, 0)
}
for _, p := range prerequisites {
graph[p[1]] = append(graph[p[1]], p[0])
}
flags := make([]int, numCourses)
for i := 0; i < numCourses; i++ {
if !canFinishDFS(graph, flags, i) {
return false
}
}
return true
}
func canFinishDFS(graph [][]int, flags []int, i int) bool {
if flags[i] == 1 {
return false
}
if flags[i] == -1 {
return true
}
flags[i] = 1
for _, j := range graph[i] {
if !canFinishDFS(graph, flags, j) {
return false
}
}
flags[i] = -1
return true
}
3.2. BFS-拓扑排序
//拓扑排序
func canFinish2(numCourses int, prerequisites [][]int) bool {
//使用邻接表表示节点之间的依赖关系
graph := make([][]int, numCourses)
for i := 0; i < len(graph); i++ {
graph[i] = make([]int, 0)
}
//入度表
indegrees := make([]int, numCourses)
//初始化邻接表和入度表
for _, p := range prerequisites {
//p[0]依赖于p[1],也就是先完成p[1]才能完成p[0]
//故记录p[1]->p[0]
graph[p[1]] = append(graph[p[1]], p[0])
indegrees[p[0]]++
}
//Kahn本质上就是BFS,故使用队列
//队列保存入度为0的节点
queue := make([]int, 0)
for i := 0; i < numCourses; i++ {
if indegrees[i] == 0 {
queue = append(queue, i)
}
}
//res := make([]int, 0)
for len(queue) > 0 {
node := queue[0]
queue = queue[1:]
//res = append(res, node)
numCourses--
for _, out := range graph[node] {
indegrees[out]--
if indegrees[out] == 0 {
queue = append(queue, out)
}
}
}
//return len(res) == numCourses
return numCourses == 0
}
讨论
使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看