leetcode -- Course Schedule I && II -- TopSort重点

来源:互联网 发布:网络支付跨行代付 编辑:程序博客网 时间:2024/06/05 14:24

https://leetcode.com/problems/course-schedule/

关于graph的题目,考察拓扑排序

Course Schedule

这里只要判断是否能拓扑排序就行,就是看graph内有没有环,是不是DAG。

拓扑排序 参考http://blog.csdn.net/dm_vincent/article/details/7714519,

思路1 Kahn算法

http://songlee24.github.io/2015/05/07/topological-sorting/
思路很简单,
- 从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
- 从图中删除该顶点和所有以它为起点的有向边。
- 重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。

这里就看当前图中是否存在无前驱的顶点就行。
code参考http://bookshadow.com/weblog/2015/05/07/leetcode-course-schedule/

class Solution:    # @param {integer} numCourses    # @param {integer[][]} prerequisites    # @return {boolean}    def canFinish(self, numCourses, prerequisites):        degrees = [0] * numCourses#记录indegree        childs = [[] for x in range(numCourses)]        for pair in prerequisites:            #这里的edge 是 pair[1] -> pair[0]            degrees[pair[0]] += 1            childs[pair[1]].append(pair[0])        courses = set(range(numCourses))        flag = True        while flag and len(courses):            flag = False            removeList = []            for x in courses:                if degrees[x] == 0:                    for child in childs[x]:                        degrees[child] -= 1                    removeList.append(x)                    flag = True            for x in removeList:                courses.remove(x)        return len(courses) == 0

思路2 DFS或者BFS

参考http://yucoding.blogspot.hk/2015/06/leetcode-question-course-schedule.html

没看太懂,再看看

自己复习重写

打算用入度出度两个dict来做,但是实际上这样的结构不方便

        in_num = {}        out_num = {}        for x in prerequisites:            if x[0] not in in_num:                in_num[x[0]] = x[1]            else:                in_num[x[0]].append(x[1])            if x[1] not in out_num:                out_num[x[1]] = x[0]            else:                out_num[x[1]].append(x[0])

还是要按照ref的数据结构,用indegree和child就行。而且初始化每一个course对应的child node为[]

class Solution(object):    def canFinish(self, numCourses, prerequisites):        """        :type numCourses: int        :type prerequisites: List[List[int]]        :rtype: bool        """        indegree = [0]*numCourses        child = [[] for x in range(numCourses)]#这里注意初始化方法,全部初始化为[]比较方便        for pair in prerequisites:            indegree[pair[0]] += 1            child[pair[1]].append(pair[0])        course = list(range(numCourses))#这里用list 就行        while len(course) > 0:            removelist = []#这里以免破坏course,在搜索完毕之后,一起remove掉            for x in course:                if indegree[x] == 0:                    removelist.append(x)                    for y in child[x]:                        indegree[y] -= 1            if len(removelist) == 0:#即没有indegree为0的course了。所以要False                return False            for x in removelist:                course.remove(x)        return True

Course Schedule II

参考http://bookshadow.com/weblog/2015/05/14/leetcode-course-schedule-ii/

把拓扑排序的结果输出即可。

这里也有上述两种思路,DFS以及BFS的思路再看看。

自己重写的code

class Solution(object):    def findOrder(self, numCourses, prerequisites):        """        :type numCourses: int        :type prerequisites: List[List[int]]        :rtype: List[int]        """        indegree = [0]*numCourses        child = [[] for x in range(numCourses)]#这里注意初始化方法,全部初始化为[]比较方便        for pair in prerequisites:            indegree[pair[0]] += 1            child[pair[1]].append(pair[0])        course = list(range(numCourses))#这里用list 就行        ans = []        while len(course) > 0:            removelist = []#这里以免破坏course,在搜索完毕之后,一起remove掉            for x in course:                if indegree[x] == 0:                    removelist.append(x)                    for y in child[x]:                        indegree[y] -= 1            if len(removelist) == 0:#即没有indegree为0的course了。所以要False                return []            for x in removelist:                ans.append(x)                course.remove(x)        return ans
0 0
原创粉丝点击