码迷,mamicode.com
首页 > 其他好文 > 详细

【LeetCode 207】Course Schedule

时间:2015-06-16 16:02:20      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:

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?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

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:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices.

 

思路:

       此题可抽象为有向图中的环检测问题。常规解法为构建邻接矩阵邻接链表后通过拓扑排序检测有向图中是否存在环路,若存在环路说明这个小朋友悲剧了即将面临辍学的危机,返回false,否则,小朋友可以任性的选课直到毕业(然而事实上即使能顺利毕业也没有什么*用)。

       在这里本人使用了两个set容器数组来构建图(考虑到也许会有重复输入等情况,还有就是懒 - -!),随后进行拓扑排序求得结果。

 

 1 class Solution {
 2 public:
 3     bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
 4 
 5         const int n = numCourses;
 6         int cnt = 0;
 7 
 8         set<int> sets[n], grap[n];
 9         queue<int> Queue;//队列,拓扑排序必备
10 
11         //从给定的输入中构建图,sets[i]表示学习课程i后才能继续学习的后置课程的集合
12         //grap[i]表示学习课程i所必须的前置课程的集合(入度)
13         vector<pair<int, int> >::iterator it = prerequisites.begin();
14         for(; it != prerequisites.end(); it++)
15         {
16             sets[(*it).second].insert((*it).first);
17             grap[(*it).first].insert((*it).second);
18         }
19 
20         //将不需要前置课程的课程(入度为0的课程)压入队列
21         for(int i = 0; i < n; i++)
22             if(grap[i].size() == 0)
23                 Queue.push(i);
24 
25         while(!Queue.empty())
26         {
27             //取出队首的课程
28             int cur = Queue.front();
29             Queue.pop();
30             //遍历当前课程
31             //遍历当前课程(cur)的后置课程,对后置课程(*it)的前置课程的集合(grap[*it])中去掉当前课程
32             //若去掉当前课程后该课程的前置课程集合为空,则将其压入队列
33             set<int>::iterator it = sets[cur].begin();
34             for(; it != sets[cur].end(); it++)
35             {
36                 grap[*it].erase(cur);
37                 if(grap[*it].size() == 0)
38                     Queue.push(*it);
39             }
40             cnt++;//统计共拓扑出了多少课程
41         }
42 
43         //若拓扑出的课程数等于总课程数,说明无环,return true,反之,return false
44         return cnt == n ? 1 : 0;
45     }
46 };

 

【LeetCode 207】Course Schedule

标签:

原文地址:http://www.cnblogs.com/tjuloading/p/4580780.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!