leetcode No207. Course Schedule

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011391629/article/details/86475169

Question

There are a total of n courses you have to take, labeled from 0 to n-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: 2, [[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: 2, [[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.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

Algorithm

这一题是典型的拓扑排序(Topological sort),在解这题之前我是没有看过图相关的算法,仅仅知道一些基本概念。学过图论的可以直接看代码了。

在解这道题之前,我们需要知道几个概念:

  • 有向图(Directed Graph)
  • 邻接表(Adjacency-list)
  • 出度(out degree)
  • 入度(in degree)

接着我们需要知道用什么数据结构来表示一张图:

  • 可以用一维结构体数组或者二维数组,这里我用二维数组

给出的Hint中写到:
This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.

这个问题的实质是判断有向图中是否存在环,如果存在环,则不存在拓扑排序(有向无环图才存在拓扑排序),也就无法上完所有课程。这里我找到一个介绍拓扑排序的博客拓扑排序(Topological Sorting)

扫描二维码关注公众号,回复: 5794123 查看本文章

For example:(BFS)
在这里插入图片描述

简单来说,步骤如下:

  1. 找一个入度为0的顶点(任意,因此拓扑排序的结果不是唯一的)
  2. 去掉这个顶点,并且删除所有连接的边
  3. 重复1.2

以拓扑排序的方法为基础,来判断有向图是否有环:
在步骤1.2.3的过程中,统计入度为0的顶点个数count,判断count是否等于图的顶点个数

For example:
一、在刚才的例子中
(1)找到1的入度为0,count+1=1
(2)找到2的入度为0,count+1=2
…最后count = 5,图中的顶点个数也是5,所以存在拓扑排序

二、题目中Example2,0->1,1->0
没有入度为0的顶点,因此count=0,顶点数为2,所以不存在拓扑排序

现在回到题目中来,那么课程就是顶点,(1,0)表示上完课程0才能上课程1,那在有向图中应该是表示0->1(这个别搞错了

Code

//step1: establish adjacency-list & count indegree
//step2: find point of indegree is zero
//step3: BFS
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<vector<int> > graph(numCourses);
        vector<int> indegree(numCourses, 0);
        
        //establish adjacency-list & count indegree
        for(auto p : prerequisites){
            graph[p.second].push_back(p.first);
            indegree[p.first]++;
        }
        
        //find point of indegree is zero
        queue<int> Q;
        for(int i=0; i<numCourses; i++){
            if(indegree[i] == 0){
                Q.push(i);
            }
        }
        
        //BFS
        int count = 0;
        while(!Q.empty()){
            int cur = Q.front();
            Q.pop();
            count++;
            for(auto cur : graph[cur]){
                indegree[cur]--;
                if(indegree[cur] == 0)
                    Q.push(cur);
            }
        }
        return count == numCourses;
    }
};

猜你喜欢

转载自blog.csdn.net/u011391629/article/details/86475169