Leetcode 207 Course Schedule

题目网址 https://leetcode-cn.com/problems/course-schedule/
There are a total of numCourses courses you have to take, labeled from 0 to numCourses-1.

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]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

Constraints:

  • The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  • You may assume that there are no duplicate edges in the input prerequisites.
  • 1 <= numCourses <= 10^5

思路分析

首先这个题目是一个非常明显的判断有向图是否有环的问题,下面是我用的两种解法

1. DFS

用dfs来处理是需要注意,如果visited数组只有两种状态,即访问过或者未访问过,那么这不足以判断有向图是否有环,因为visited数组中存了三种状态
(1)访问已完成
(2)正在访问
(3)尚未访问
只有当我们访问到标记为状态(2)的节点才说明有有向环,因为如果访问到了标记为状态(2)的节点,则说明在访问此节点的子孙节点时有重新访问了此节点,那么就会形成一个有向环。
代码如下:

class Solution {
public:
    vector> graph;
    vector visited;
    bool ans=true;
    void dfs(int i, vector>& graph, vector& visited){
        if(ans==false)return;
        if(visited[i]==2){
            return;
        }
        if(visited[i]==1){
            ans = false;
            return;
        }
        visited[i]=1;
        for(auto node:graph[i]){
            dfs(node, graph, visited);
        }
        visited[i]=2;
    }
    bool canFinish(int numCourses, vector>& prerequisites) {
        graph.resize(numCourses);
        visited.resize(numCourses);
        for(auto edge:prerequisites){
            graph[edge[1]].push_back(edge[0]);
        } 
        for(int i=0;i

2. 拓扑排序(BFS)

首先将所有入度为0的节点加入queue,依次删除队列中节点的出度对应的边并把更新过后入度为0的节点加入queue,直到队列为空。最后需要检查在此操作之后是不是所有的节点入度都为0,如果不是则存在环。
代码如下:

class Solution {
public:
    vector> graph;
    vector indegree;
    bool canFinish(int numCourses, vector>& prerequisites) {
        graph.resize(numCourses);
        indegree.resize(numCourses);
        for(auto edge:prerequisites){
            graph[edge[1]].push_back(edge[0]);
            indegree[edge[0]]++;
        } 
        queue q;
        for(int i=0;i

这题是图的典型题目,需要重视起来!就酱~

你可能感兴趣的:(Leetcode 207 Course Schedule)