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

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

你可能感兴趣的:(LeetCode)