Featured image of post 210. 课程表 II

210. 课程表 II

题目描述

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai必须 先选修 bi

  • 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1]

返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组

示例 1:

  • 输入:numCourses = 2, prerequisites = [[1,0]]
  • 输出:[0,1]
  • 解释:总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

  • 输入:numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
  • 输出:[0,2,1,3]
  • 解释:总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。 因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

示例 3:

  • 输入:numCourses = 1, prerequisites = []
  • 输出:[0]

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • ai != bi
  • 所有 [ai, bi] 互不相同

解法一:DFS + 后序遍历

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
func findOrder(numCourses int, prerequisites [][]int) []int {
    n := numCourses
    var ans []int
    visited := make([]int, n)
    prevCourses := make([][]int, n)
    for _, pair := range prerequisites {
        prevCourses[pair[0]] = append(prevCourses[pair[0]], pair[1])
    }
    var dfs func(id int) bool
    dfs = func(id int) bool {
        if visited[id] == 1 {
            return false
        } else if visited[id] == 2 {
            return true
        }
        visited[id] = 1
        for _, prev := range prevCourses[id] {
            if !dfs(prev) {
                // visited[id] = 1
                return false
            }
        }
        ans = append(ans, id)
        visited[id] = 2
        return true
    }
    for id := 0; id < n; id++ {
        if !dfs(id) {
            return []int{}
        }
    }
    return ans
}

解法二:BFS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
func findOrder(numCourses int, prerequisites [][]int) []int {
    n := numCourses
    var ans []int
    afterCourses := make([][]int, n)
    // indeg[i] 为编号为 i 的节点的入度
    indeg := make([]int, n)
    for _, pair := range prerequisites {
        afterCourses[pair[1]] = append(afterCourses[pair[1]], pair[0])
        indeg[pair[0]]++
    }
    var queue []int
    for i := 0; i < n; i++ {
        if indeg[i] == 0 {
            queue = append(queue, i)
        }
    }
    for len(queue) > 0 {
        cur := queue[0]
        queue = queue[1:]
        for _, v := range afterCourses[cur] {
            indeg[v]--
            if indeg[v] == 0 {
                queue = append(queue, v)
            }
        }
        ans = append(ans, cur)
    }
    if len(ans) != n {
        return []int{}
    }
    return ans
}
Licensed under CC BY-NC-SA 4.0
最后更新于 2023/08/07 13:04:32
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计