题目地址:Course Schedule - LeetCode


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 shouldalso 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.


这道题目是我在XX公司面试时遇到的算法题,当时就看出来这是判断有向图(DAG)是否存在环。
一时想不起算法,于是就自己实现了一个时间复杂度为O(V^2)的算法,面试官自然不满意,于是当时现场又用递归的做法实现了时间复杂度为O(N+V)的算法(dfs),这个做法只是口述了一遍,并没有真的实现。现在想想实现起来还是非常复杂的。

刚刚我实现了O(V^2)的算法,发现算法有bug,尴尬了。
然后实现自己的DFS算法,花了至少20分钟,现场做肯定做不出来。

DFS-Python解法如下:

class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:s = {}res = set()flag = 0def helper(begin=-1, find=set()):nonlocal flag, res, sfor i in s[begin]:if i not in res:if i in find:flag = 1returnfind.add(i)helper(i, find=find)res.add(begin)for i in range(0, numCourses):s[i] = set()for i in prerequisites:s[i[0]].add(i[1])for i in range(0, numCourses):helper(begin=i, find={i})if flag == 1:return Falsereturn True

代码不好,别人写的优化过的代码如下:

class Solution(object):def canFinish(self, numCourses, prerequisites):""":type numCourses: int:type prerequisites: List[List[int]]:rtype: bool"""graph = [[] for _ in range(numCourses)]visited = [0 for _ in range(numCourses)]# create graphfor pair in prerequisites:x, y = pairgraph[x].append(y)# visit each nodefor i in range(numCourses):if not self.dfs(graph, visited, i):return Falsereturn Truedef dfs(self, graph, visited, i):# if ith node is marked as being visited, then a cycle is foundif visited[i] == -1:return False# if it is done visted, then do not visit againif visited[i] == 1:return True# mark as being visitedvisited[i] = -1# visit all the neighboursfor j in graph[i]:if not self.dfs(graph, visited, j):return False# after visit all the neighbours, mark it as done visitedvisited[i] = 1return True

随后看到另外一位大佬用OOP的思想重写了代码,虽然速度没有提升,但思路清晰多了:

class Solution:class Course(object):def __init__(self):self.being_visit, self.visit_done = False, Falseself.pre_course = []def is_cyclic(self):if self.visit_done is True:return Falseif self.being_visit is True:return Trueself.being_visit = Truefor course in self.pre_course:if course.is_cyclic():return Trueself.being_visit = Falseself.visit_done = Truereturn Falsedef canFinish(self, num_courses, prerequisites) -> bool:l = [self.Course() for _ in range(0, num_courses)]for (course1, course2) in prerequisites:l[course1].pre_course.append(l[course2])for i in range(0, num_courses):if l[i].is_cyclic():return Falsereturn True

标准的更正式更快的解法是拓扑排序(Topological Sorting),可以参考:Kahn’s algorithm for Topological Sorting - GeeksforGeeks

class Solution:def canFinish(self, num_courses, prerequisites) -> bool:vertices = num_coursesadj_list = [[] for _ in range(0, vertices)]in_degree = [0 for _ in range(0, vertices)]for (course1, course2) in prerequisites:adj_list[course1].append(course2)in_degree[course2] += 1q = [i for i in range(0, vertices) if in_degree[i] == 0]count = 0while q:front = q.pop(0)for i in adj_list[front]:in_degree[i] -= 1if in_degree[i] < 0:return Falseelif in_degree[i] == 0:q.append(i)count += 1if count == vertices:return Trueelse:return False

LeetCode 207. Course Schedule--有向图找环--面试算法题--DFS递归,拓扑排序迭代--Python相关推荐

  1. LeetCode 221. Maximal Square----动态规划--谷歌面试算法题--Python解法

    题目地址:Maximal Square - LeetCode Given a 2D binary matrix filled with 0's and 1's, find the largest sq ...

  2. 【LintCode 题解】小米面试算法题:搜索旋转排序数组

    题目描述 假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2).给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回 ...

  3. 【面试算法题】十种常用排序算法详解

    排序算法的稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,如果排序以后,保证这些记录的相对次序保持不变,即在原序列中,a[i]=a[j],且 a[i] 在 a[j] 之前,排序后保 ...

  4. [Leetcode][第207题][JAVA][课程表][拓扑排序][DFS]

    [问题描述][中等] [解答思路] 1. 拓扑排序 复杂度分析 HashSet[] 数组 import java.util.HashSet; import java.util.LinkedList; ...

  5. [Leedcode][JAVA][第210 题][课程表 II][拓扑排序][BFS][DFS][有向图]

    [问题描述][第210 题][课程表 II][中等] 现在你总共有 n 门课需要选,记为 0 到 n-1.在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用 ...

  6. 力扣高频算法php_互联网公司最常见的面试算法题有哪些?

    很多时候,你即使提前复习了这些最常见的面试算法题,你依旧无法通过算法面试! 为什么?你在提前准备复习的时候,在网上找了半天相应题目的分析文章,但你看了就是不懂. 你在面试的时候,卡壳了,一时间忘了怎么 ...

  7. 互联网公司最常见的面试算法题大集合!

      转载于 新智元   来源:Github 编辑:元子 [导读]LeetCode是一个美国的在线编程网站,收集了各个大厂的笔试面试题,对找工作的毕业生和开发者来说,非常有价值.很多求职者都会在Leet ...

  8. C++经典面试算法题

    #include <assert.h> #include <string.h> #include <stack>// // C++ 经典面试算法题 [7/28/20 ...

  9. 常考面试算法题类型总结(来自知乎)

    作者:牛客网 链接:https://www.zhihu.com/question/24964987/answer/200681301 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

最新文章

  1. python实现卡方(Chi-Squared Test)相关性检验
  2. pandas索引和选择数据
  3. 怎样把pdf转换成word
  4. 北京理工大学 python专题课程-Python第七章(北理国家精品课 嵩天等)
  5. php中jquery ajax请求参数,浅谈Jquery中Ajax异步请求中的async参数的作用
  6. 使用Travis-CI的SpringBoot应用程序的CI / CD
  7. Spring IOC扫描器与注册器
  8. Tomcat 项目代码上线步骤详解
  9. 怎样在WIN7系统下安装IIS和配置ASP
  10. 海贼王热血航线正在连接服务器,海贼王热血航线为什么连接不了服务器?老是说人已满进不去?...
  11. Cortex-M3技术参考手册 2022年3月1日
  12. NLP 常用模型和数据集高速下载
  13. http方法有哪些?get、post、put、delete,为什么一般只用过get和post?什么时候用put、delete,为什么没用过
  14. 怎样下载网页内视频文件
  15. js转换php时间戳,js对时间戳转换的方法
  16. 使用某为开发板,在项目过程中遇到的坑,记录一下,希望以后不会遇到
  17. XML用户界面语言(XUL)开发入门(2)
  18. 婚恋职场人格-张晓文-武汉理工大学-中国MOOC-我是谁?测试题参考答案
  19. 前端工程师实战17:详解CSS背景图片、雪碧图
  20. 海康威视:AI 芯片很难被管制,海外市场值得期待

热门文章

  1. Science | 机器学习揭示了构建人造蛋白质的秘诀
  2. 哈佛CASTER | 基于化学子结构表征预测药物相互作用
  3. 贝叶斯优化-matlab
  4. mysql groupby having_mysql group by having的使用方法
  5. 在springcacheinvokecontext中没找到field_家庭中没入住多久玻璃胶就发黑发霉,终于找到它的原因了,很简单...
  6. 英伟达人工智能和处理器驱动的制药、生命科学合作
  7. 香港浸会大学张璐博士和卞兆祥教授联合招聘生物信息学博士后
  8. 宏基因组蚂蚁森林合种——胡杨专车
  9. R语言:生成正态分布数据生成--rnorm,dnorm,pnorm,qnorm
  10. PNAS-2018-多年多点5千样本鉴定玉米根际可遗传微生物