LeetCode 1462. コース スケジュール IV: トポロジカル ソート

【LetMeFly】1462. カリキュラム IV: トポロジカルソート

Leetcode の質問リンク: https://leetcode.cn/problems/course-schedule-iv/

合計のコースを受講する必要があり numCourses 、コース番号は0 順番 に並んでいますnumCourses-1 。コースを 選択する場合は 、 最初にコースを選択する 必要があることを示す配列が表示されます prerequisite。 prerequisites[i] = [ai, bi]biai

  • 一部のコースには直接の前提条件コースがあり、たとえば、コースを受講したい場合は、1 最初にコースを受講する必要があり0 、その後、[0,1] 前提条件コースのペアの数がペアの形式で提供されます。

前提条件は間接的なものにすることもできますcourseabcourse の前提条件であり、 course がcourse の前提条件でbある場合、 course はcourse の前提条件になります。cac

queries を使用して 配列も取得できます queryでは、 そのコースがコースの前提条件であるかどうかを 回答する必要があります  。queries[j] = [uj, vj]jujvj

がクエリに対する答えansweranswer[j]あるブール配列を返します。j

 

例 1:

入力: numCourses = 2、prerequisites = [[1,0]]、queries = [[0,1],[1,0]]
出力: [false,true]
説明:コース 0 はコース 1 の前提条件コースではありません, ただし、コース1はコース0の前提コースです。

例 2:

入力: numCourses = 2、prerequisites = []、queries = [[1,0],[0,1]]
出力: [false,false]
説明:前提条件コースのペアがないため、各コースは独立しています。

例 3:

入力: numCourses = 3、前提条件 = [[1,2],[1,0],[2,0]]、クエリ = [[1,0],[1,2]] 出力: [ true ,
 true ]

 

ヒント:

  • 2 <= numCourses <= 100
  • 0 <= prerequisites.length <= (numCourses * (numCourses - 1) / 2)
  • prerequisites[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi
  • すべてのペア は異なり ます[ai, bi]
  • 前提条件図にはリングがありません。
  • 0 <= ui, vi <= n - 1
  • ui != vi

方法 1: トポロジカルソート

まず第一に、コースの順序を決定するという点で、この質問はLeetCode 207. カリキュラムに似ており、トポロジカル ソートを使用して解くことができます。

つまり、問題は1 0 4 10^4です。1 04 つのクエリ。各クエリをすばやく返すにはどうすればよいですか?

num Courses × num Courses numCourses\times numCoursesを作成できます。コース_ _ _ _ _×ブール配列nu m Courses PreisPreis Pre [a] [b ] isPre[a ] [ b]is P re [ a ] [ b ]コースaaaがコースbbかどうかbの前提条件科目。(このようにして、特定のクエリに対してqqq、単にis P re [ q [ 0 ] ] [ q [ 1 ] ] isPre[q[0]][q[1]] をis Pre [ q [ 0 ]] [ q [ 1 ]]とすることできます)

トポロジカルソートでは、thisCourse が nextCourse の前提条件コースであると判断された場合、 thisCourse のすべての前提条件コースが nextCourse の前提条件コースになります式で表すと次のようになります。

∀ 0 ≤ i ≤ num Courses , is Pre [ i ] [ 次のコース ] ∣ = is P re [ i ] [ このコース ] \forall 0\leq i\leq numCourses,\ \ isPre[i][次のコース]\ \ |=\ isPre[i][このコース]∀0コース_ _ _ _ _  is Pre [ i ] [コース] _ _ _ _ _ _  = is Pre [ i ] [このコース] _ _ _ _ _ _ _

  • 時間計算量O ( コース数 2 + n + q ) O(コース数^2 + n + q)O (コース_ _ _ _ _ _2+n+q )、ここでnnnは前提条件のコース関係係数、qqqはクエリの数です
  • スペースの複雑さO ( コース数 2 + n ) O(コース数^2 + n)O (コース_ _ _ _ _ _2+n )

ACコード

C++

class Solution {
    
    
public:
    vector<bool> checkIfPrerequisite(int numCourses, vector<vector<int>>& prerequisites, vector<vector<int>>& queries) {
    
    
        // 建图
        vector<vector<int>> graph(numCourses);
        vector<int> indegree(numCourses);
        for (vector<int>& ab : prerequisites) {
    
    
            graph[ab[0]].push_back(ab[1]);
            indegree[ab[1]]++;
        }

        // 初始化队列
        queue<int> q;
        for (int i = 0; i < numCourses; i++) {
    
    
            if (!indegree[i]) {
    
    
                q.push(i);
            }
        }

        // 预处理(拓扑排序)
        vector<vector<bool>> isPre(numCourses, vector<bool>(numCourses, false));
        while (q.size()) {
    
    
            int thisCourse = q.front();
            q.pop();
            for (int nextCourse : graph[thisCourse]) {
    
    
                indegree[nextCourse]--;
                if (!indegree[nextCourse]) {
    
    
                    q.push(nextCourse);
                }
                isPre[thisCourse][nextCourse] = true;
                for (int i = 0; i < numCourses; i++) {
    
    
                    isPre[i][nextCourse] = isPre[i][nextCourse] | isPre[i][thisCourse];  // vector不支持|=
                }
            }
        }

        // 查询
        vector<bool> ans;
        for (vector<int>& q : queries) {
    
    
            ans.push_back(isPre[q[0]][q[1]]);
        }
        return ans;
    }
};

パイソン

# from typing import List

class Solution:
    def checkIfPrerequisite(self, numCourses: int, prerequisites: List[List[int]], queries: List[List[int]]) -> List[bool]:
        graph = [[] for _ in range(numCourses)]
        indegree = [0] * numCourses
        for a, b in prerequisites:
            graph[a].append(b)
            indegree[b] += 1
        
        q = []
        for i in range(numCourses):
            if not indegree[i]:
                q.append(i)
        
        isPre = [[False for _ in range(numCourses)] for __ in range(numCourses)]
        while q:
            thisCourse = q.pop()
            for nextCourse in graph[thisCourse]:
                indegree[nextCourse] -= 1
                if not indegree[nextCourse]:
                    q.append(nextCourse)
                isPre[thisCourse][nextCourse] = True
                for i in range(numCourses):
                    isPre[i][nextCourse] |= isPre[i][thisCourse]
        
        ans = []
        for a, b in queries:
            ans.append(isPre[a][b])
        return ans

記事は CSDN に同時公開されています。オリジナルであることは簡単ではありません。著者の同意を得て転載した後、元の記事へのリンクを添付してください~
Tisfy: https://letmefly.blog.csdn.net/article/details/132825649

おすすめ

転載: blog.csdn.net/Tisfy/article/details/132825649