leetcode(207). Course Schedule
来源:互联网 发布:js一切皆对象 编辑:程序博客网 时间:2024/06/05 00:44
problem
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. Read more about how a graph is
represented. You may assume that there are no duplicate edges in the
input prerequisites.
分析
这个问题可以抽象为判断一个图中是否有环,可以有两种算法,一种是迭代的删除所有入度为零的节点和它的边,另一种由于深度优先搜索中出现重复节点和有环是等价的,因此我们可以对图进行dfs。
#超过10%class Solution(object): def canFinish(self, numCourses, prerequisites): """ :type numCourses: int :type prerequisites: List[List[int]] :rtype: bool """ g = {i:set() for i in range(numCourses)} for i, j in prerequisites: g[i].add(j) while True: #所有入度为零的节点 tmp = [i for i in g if not g[i]] if not tmp: break for i in tmp: #删除节点 del g[i] for v in g.values(): #删除边 if i in v: v.remove(i) return g == {}
树和图都可以使用dict(+set)来实现
DFS
实际上使用DFS不仅可以判断图中是否有环,还可以输出图的拓扑排序(将图转化为一维序列,使得对图中任意边uv,排序时u都出现在v之前)。
图的DFS和树的差不多,只不过在树中不会出现环,但是在图中如果出现环会无限循环,所以必须记录下已访问的节点。
class Solution(object): def canFinish(self, numCourses, prerequisites): """ :type numCourses: int :type prerequisites: List[List[int]] :rtype: bool """ g = [[] for _ in range(numCourses)] for a, b in prerequisites: g[b].append(a) visited = [0 for _ in range(numCourses)] def dfs(node, visited): visited[node] = 1 for v in g[node]: #使用for保存接下来要访问的节点 if visited[v] == 1: return False elif visited[v] == 0: if not dfs(v, visited): return False visited[node] = 2 return True for i in range(numCourses): if visited[i] == 0: if not dfs(i, visited): #print visited return False return True
visit中的0表示未访问,1表示此次遍历的节点,2表示之前访问的节点,之所以有三种标记是因为防止从中间开始也可以碰到已访问节点,例如2→1→3,从1开始访问,2也会碰到已访问节点,所以使用两种标记不行。
参考文献:
https://www.cs.usfca.edu/~galles/visualization/TopoSortDFS.html
http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/
http://www.geeksforgeeks.org/topological-sorting/
- LeetCode 207 - Course Schedule
- leetcode 207: Course Schedule
- LeetCode 207-Course Schedule
- 【Leetcode】Course Schedule #207
- LeetCode 207 Course Schedule
- LeetCode(207)Course Schedule
- leetcode 207: Course Schedule
- [LeetCode 207] Course Schedule
- 【LEETCODE】207-Course Schedule
- LeetCode 207 Course Schedule
- LeetCode 207 Course Schedule
- LeetCode 207 Course Schedule
- Leetcode 207 Course Schedule
- Leetcode 207 Course Schedule
- leetcode(207). Course Schedule
- Leetcode-207: Course Schedule
- LeetCode #207 Course Schedule
- leetcode 207 Course Schedule
- charles+SwitchyOmega抓取https网站
- 用Bitmap结构保存opencv中的单通道(8位)图像保存为png8
- C之有趣-strlen()函数引发的一场“血案”
- Redis 批量删除键
- 深入理解计算机操作系统(2.2.7)
- leetcode(207). Course Schedule
- 文章标题
- 关于中文乱码的问题
- 递归与动态规划---最长递增子序列问题
- 源码(五)
- LintCode 买卖股票的最佳时期I II III 之Python 代码
- 新笔记本安装ubuntu17.0后黑屏只能外界显示器解决办法,只是经验
- jQuery1
- ajax