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:

, [[,]]

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

, [[,],[,]]

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.

思路:

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

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

 class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) { const int n = numCourses;
int cnt = ; set<int> sets[n], grap[n];
queue<int> Queue;//队列,拓扑排序必备 //从给定的输入中构建图,sets[i]表示学习课程i后才能继续学习的后置课程的集合
//grap[i]表示学习课程i所必须的前置课程的集合(入度)
vector<pair<int, int> >::iterator it = prerequisites.begin();
for(; it != prerequisites.end(); it++)
{
sets[(*it).second].insert((*it).first);
grap[(*it).first].insert((*it).second);
} //将不需要前置课程的课程(入度为0的课程)压入队列
for(int i = ; i < n; i++)
if(grap[i].size() == )
Queue.push(i); while(!Queue.empty())
{
//取出队首的课程
int cur = Queue.front();
Queue.pop(); //遍历当前课程(cur)的后置课程集合
//在每一个后置课程(*it)的前置课程的集合(grap[*it])中去掉当前课程
//若去掉当前课程后该课程的前置课程集合为空,则将其压入队列
set<int>::iterator it = sets[cur].begin();
for(; it != sets[cur].end(); it++)
{
grap[*it].erase(cur);
if(grap[*it].size() == )
Queue.push(*it);
}
cnt++;//统计共拓扑出了多少课程
} //若拓扑出的课程数等于总课程数,说明无环,return true,反之,return false
return cnt == n ? : ;
}
};

【LeetCode 207】Course Schedule的更多相关文章

  1. 【LeetCode 229】Majority Element II

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  2. 【LeetCode练习题】Permutation Sequence

    Permutation Sequence The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and ...

  3. 【LeetCode题解】二叉树的遍历

    我准备开始一个新系列[LeetCode题解],用来记录刷LeetCode题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有 ...

  4. 【LeetCode题解】136_只出现一次的数字

    目录 [LeetCode题解]136_只出现一次的数字 描述 方法一:列表操作 思路 Java 实现 Python 实现 方法二:哈希表 思路 Java 实现 Python 实现 方法三:数学运算 思 ...

  5. 【LeetCode题解】7_反转整数

    目录 [LeetCode题解]7_反转整数 描述 方法一 思路 Java 实现 类似的 Java 实现 Python 实现 方法二:转化为求字符串的倒序 Java 实现 Python 实现 [Leet ...

  6. 【LeetCode题解】350_两个数组的交集Ⅱ

    目录 [LeetCode题解]350_两个数组的交集Ⅱ 描述 方法一:映射 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 Python 实现 [Lee ...

  7. 【LeetCode题解】349_两个数组的交集

    目录 [LeetCode题解]349_两个数组的交集 描述 方法一:两个哈希表 Java 实现 类似的 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 ...

  8. 【LeetCode题解】94_二叉树的中序遍历

    目录 [LeetCode题解]94_二叉树的中序遍历 描述 方法一:递归 Java 代码 Python代码 方法二:非递归 Java 代码 Python 代码 [LeetCode题解]94_二叉树的中 ...

  9. 【LeetCode题解】144_二叉树的前序遍历

    目录 [LeetCode题解]144_二叉树的前序遍历 描述 方法一:递归 Java 代码 Python 代码 方法二:非递归(使用栈) Java 代码 Python 代码 [LeetCode题解]1 ...

随机推荐

  1. asp.net-(含:模拟登陆,照片列表)

    一.画好用户登录界面 同时换下请求的地址. 获取用户信息及判断代码插入位置: 一.画好用户登录界面 同时换下请求的地址. 获取用户信息及判断代码插入位置: <%@ WebHandler Lang ...

  2. 黑马程序员-C#学习笔记(二)

    ---------------------- ASP.Net+Android+IOS开发..Net培训.期待与您交流! ---------------------- - C# 学习笔记 一.变量与表达 ...

  3. 防止注入网上查了下用SqlParameter可以,那SqlParameter处理单引号时候是自动转义了吗

    String sql = String.Format(); SqlCommand com = new SqlCommand(sql, con); 一般而言,把 一个单引号,替换成 两个单引号就可以了.

  4. 小心!#define max(a,b) a>b?a:b

    今天做oj的时候,定义了两个宏: //wrong code#define max_2(a,b) a>b?a:b #define max_3(a,b,c) (a>b?a:b)>c?(a ...

  5. 【PHPsocket编程专题(实战篇③)】构建基于socket的HTTP请求类

    该代码是两年前写的,现在看起来有点渣了,仅仅是提供一个思路,现在做一些Api开发的时候官方会有一些SDK,这些SDK其实原理都是通过socket来通讯的,其实我个人主张用curl更方便,当然前提是你的 ...

  6. Spring整合CXF,发布RSETful 风格WebService(转)

    Spring整合CXF,发布RSETful 风格WebService 这篇文章是承接之前CXF整合Spring的这个项目示例的延伸,所以有很大一部分都是一样的.关于发布CXF WebServer和Sp ...

  7. PCL—低层次视觉—点云分割(最小割算法)

    1.点云分割的精度 在之前的两个章节里介绍了基于采样一致的点云分割和基于临近搜索的点云分割算法.基于采样一致的点云分割算法显然是意识流的,它只能割出大概的点云(可能是杯子的一部分,但杯把儿肯定没分割出 ...

  8. hadoop拾遗(二)---- 文件模式

    在单个操作中处理一批文件,这是一个常见的要求.举例来说,处理日志的MapReduce作业可能需要分析一个月内包含在大量目录中的日志文件.在一个表达式中使用通配符来匹配多个文件是比较方便的,无需列举第个 ...

  9. PHP Redis 普通封装类

    class redisInit { private $redis; //redis对象 /** * 初始化Redis * $config = array( * 'server' => '127. ...

  10. uboot---linux

    01uboot是没有虚拟地址的 02内存映射是linux内核的机制,也就是从实地址到虚拟地址是linux完成的! -----