207. Course Schedule(课程表)
题目大意
There are a total of numCourses
courses you have to take, labeled from 0 to numCourses - 1
. You are given an array prerequisites
where prerequisites[i] = [ai, bi]
indicates that you must take course bi
first if you want to take course ai
.
For example, the pair [0, 1]
, indicates that to take course 0 you have to first take course 1.
Return true if you can finish all courses. Otherwise, return false.
中文释义
你总共要上 numCourses
门课程,从 0 到 numCourses - 1
进行标记。你会得到一个数组 prerequisites
,其中 prerequisites[i] = [ai, bi]
表示如果你想上 ai
课程,你必须先上 bi
课程。
例如,对 [0, 1]
这对来说,意味着要上 0 课程,你必须先上 1 课程。
如果你能完成所有课程,返回 true。否则,返回 false。
示例
- 示例 1:
- 输入:
numCourses = 2
,prerequisites = [[1,0]]
- 输出:
true
- 解释:总共有 2 门课程要上。
要上课程 1,你应该已经完成了课程 0。所以这是可能的。
- 输入:
- 示例 2:
- 输入:
numCourses = 2
,prerequisites = [[1,0],[0,1]]
- 输出:
false
- 解释:总共有 2 门课程要上。
要上课程 1,你应该已经完成了课程 0,并且要上课程 0,你也应该已经完成了课程 1。所以这是不可能的。
- 输入:
限制条件
1 <= numCourses <= 2000
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
- 所有
prerequisites[i]
对都是唯一的。
解题思路
使用深度优先搜索(DFS)来解决问题。创建一个图来表示课程之间的先修关系,并使用 DFS 检测图中是否存在环。
步骤说明
- 构建一个图,其中每个节点表示一个课程,边表示先修关系。
- 遍历每个课程:
- 如果在 DFS 中检测到环,返回 false。
- 否则,继续检查下一个课程。
- 如果所有课程都被成功检查,没有发现环,返回 true。
代码
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> graph(numCourses);
vector<int> visit(numCourses, 0);
for (auto& pre : prerequisites)
graph[pre[1]].push_back(pre[0]);
for (int i = 0; i < numCourses; i++) {
if (!dfs(graph, visit, i)) {
return false;
}
}
return true;
}
bool dfs(vector<vector<int>>& graph, vector<int>& visit, int i) {
if (visit[i] == 1) return false;
if (visit[i] == 2) return true;
visit[i] = 1;
for (int j : graph[i])
if (!dfs(graph, visit, j))
return false;
visit[i] = 2;
return true;
}
};