[LeetCode in Python] 207 (M) course schedule

topic

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

You must take numCourse courses this semester, denoted as 0 to numCourse-1.
Some prerequisite courses are required before taking certain courses. For example, if you want to study course 0, you need to complete course 1 first. We use a match to represent them: [0,1]
Given the total number of courses and their prerequisites, please judge whether it is possible to complete all courses?

Example 1:

Input: 2, [[1,0]]
Output: true
Explanation: There are 2 courses in total. Before studying course 1, you need to complete course 0. So this is possible.

Example 2:

Input: 2, [[1,0], [0,1]]
Output: false
Explanation: There are 2 courses in total. Before learning course 1, you need to complete course 0; and before learning course 0, you should also complete course 1. This is impossible.
 
prompt:

The prerequisite for input is the graph represented by the edge list, not the adjacency matrix. For details, please refer to the diagram representation.
You can assume that there are no duplicate edges in the input prerequisites.
1 <= numCourses <= 10 ^ 5

Problem-solving ideas

This question is actually to find a ring in the picture.

  • Topological Sorting
  • First build the graph according to the order of the courses
  • Initialize the course state array, initialized to not accessed
  • There are three kinds of status: not visited, visiting, visited
  • Traverse all nodes of the graph and perform DFS on each node
  • After DFS comes in, check the state array,
    • If the current node status is accessing, it means there is a ring, return False
    • If the current node status is visited, it means that there is no need to continue, return True
    • The remaining state is unvisited,
      • First set the status of this node to access
      • If there are subsequent nodes on this node, iterate through the subsequent nodes, DFS on each node and check the return value
      • Finally, set the status of this node as visited
  • If there is a ring, the above process will return False, otherwise return True

Code

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        # - build graph
        g = defaultdict(list)
        for a,b in prerequisites:
            g[b].append(a)

        # - course status
        # - 0: unvisited, 1: visiting, 2: visited
        status_list = [0] * numCourses

        # - dfs
        def dfs(course):
            # - if the course is in visiting, means loop found
            if status_list[course] == 1: return False

            # - if the course is visited, it is ok
            if status_list[course] == 2: return True

            # - set status as visiting
            status_list[course] = 1

            # - traverse all next courses if has them
            if course in g:
                for c in g[course]:
                    if not dfs(c): return False

            # - set status as visited
            status_list[course] = 2

            return True

        # - check all courses
        for course in g:
            if not dfs(course): 
                return False

        return True

Guess you like

Origin www.cnblogs.com/journeyonmyway/p/12702667.html