[LeetCode в Python] 210 (M) расписание курсов II

титульный

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

Теперь у вас есть на выбор n курсов, записанных от 0 до n-1.
Некоторые обязательные курсы требуются перед прохождением определенных курсов. Например, если вы хотите изучать курс 0, вам сначала нужно пройти курс 1. Мы используем совпадение, чтобы представить их: [0,1]
Учитывая общее количество курсов и их предпосылки, вернитесь к запланированному вами завершению всех курсов. заказ.
Может быть несколько правильных последовательностей, вам просто нужно вернуть одну. Если невозможно пройти все курсы, верните пустой массив.

Пример 1:

Входные данные: 2, [[1,0]]
Выходные данные: [0,1]
Объяснение: Всего есть 2 курса. Чтобы пройти курс 1, сначала нужно пройти курс 0. Следовательно, правильный порядок курса [0,1].

Пример 2:

Вход: 4, [[1,0], [2,0], [3,1], [3,2]]
Выход: [0,1,2,3] или [0,2,1,3]
Пояснение: всего 4 курса. Для изучения курса 3, вы должны сначала пройти курс 1 и курс 2. И Курс 1, и Курс 2 должны быть ранжированы после Курса 0.
  Следовательно, правильный порядок курса [0,1,2,3]. Другой правильный порядок - [0,2,1,3].

Описание:

Предварительным условием для ввода является график, представленный списком ребер, а не матрицей смежности. Для получения подробной информации, пожалуйста, обратитесь к представлению схемы.
Можно предположить, что во входных предпосылках нет повторяющихся ребер.

Советы:

Эта проблема эквивалентна нахождению цикла в ориентированном графе.
Если есть цикл, топологическая сортировка отсутствует, поэтому невозможно выбрать все курсы для обучения.
Топологическая сортировка также может быть выполнена через BFS.

Идеи решения проблем

  • BFS + Неправильно делать топологическую сортировку, чувствую себя лучше, чем DFS
  • Инициализировать массив в градусах до 0,
  • Построить график и обновить массив в градусах
  • Вынуть элемент со степенью 0 и поставить его в очередь q
  • Стандартный процесс BFS
    • Всплывающий элемент в левой части очереди
    • Добавьте его в список результатов
    • Обработать все последующие элементы элемента
      • Проникновение -1
      • Если в степени == 0, добавить в очередь
  • Наконец, проверьте длину очереди результатов, если она неполная, значит, есть кольцо

код

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        # - in degree for all courses
        in_degree_list = [0] * numCourses

        # - build graph, update in_degree_list
        g = defaultdict(list)
        for a,b in prerequisites:
            g[b].append(a)
            in_degree_list[a] += 1
        
        # - put all courses which has 0 in degree into queue
        q = [c for c,d in enumerate(in_degree_list) if d==0]

        # - BFS
        res = []
        while q:
            # - handle head
            c = q.pop(0)

            # - update result
            res.append(c)

            # - BFS
            if c in g:
                for next_course in g[c]:
                    # - update in degree
                    in_degree_list[next_course] -= 1

                    # - if in degree of next course is 0, put in queue
                    if in_degree_list[next_course] == 0:
                        q.append(next_course)
        
        if len(res) == numCourses:
            return res
        else:
            return []

рекомендация

отwww.cnblogs.com/journeyonmyway/p/12702708.html