NOTE

课程表

课程表问题:DFS 与 BFS 拓扑排序。

Data Structures & Algorithms创建于 更新于 约 1 分钟读完historical

这是历史学习笔记,可能存在过时或不完整的理解。

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
}

4. 参考

讨论

使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看