【LetMeFly】1462. 커리큘럼 IV: 위상 정렬
Leetcode 질문 링크: https://leetcode.cn/problems/course-schedule-iv/
총 과목수를 이수해야 하며 numCourses
, 과목번호는 0
순서 대로 되어 있습니다 numCourses-1
. 강좌를 선택하려면 먼저 강좌를 선택 해야prerequisite
함을 나타내는 배열을 얻게 됩니다 .prerequisites[i] = [ai, bi]
bi
ai
- 일부 교과목에는 선수과목이 직접 개설되어 있는데, 예를 들어 한 과목을 수강하고자 할 경우
1
먼저 수강하여야 하며0
,[0,1]
선수과목의 개수가 짝을 이루는 형태로 부여됩니다.
전제 조건은 간접적 일 수도 있습니다 . 강좌가 a
강좌 b
의 전제 조건이고 강좌가 강좌의 전제 조건이라면 강좌는 b
강좌 의 전제 조건 입니다 .c
a
c
또한 queries
. _ 질의 의 경우 해당 과목이 해당 과목의 선수과목 인지 여부를 답변해야 합니다 .queries[j] = [uj, vj]
j
uj
vj
쿼리에 대한 답변이 있는 answer
부울 배열을 반환합니다 .answer[j]
j
예시 1:
입력: numCourses = 2, 전제 조건 = [[1,0]], 쿼리 = [[0,1],[1,0]] 출력: [false,true] 설명: 과정 0은 과정 1의 전제 과정이 아닙니다. 단, 1과정은 0과정의 선수과목이다.
예시 2:
입력: numCourses = 2, 전제 조건 = [], 쿼리 = [[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. Curriculum 과 유사하며 , 이는 위상 정렬을 이용하여 풀 수 있다 .
따라서 문제는 1 0 4 10^4 입니다.1 04개의 쿼리, 각 쿼리를 빠르게 반환하는 방법은 무엇입니까?
우리는 num C ourses × num C ourses numCourses\times numCourses를 생성할 수 있습니다.n u m 강좌 _ _ _×불리언 유형의 배열 n u m C o u rses is Pre isPrei s P re。is Pre [ a ] [ b ] isPre[a][b]i s Pre [ a ] [ b ]는 코스 aa를 나타냅니다.a가 코스 인지bbb 의 필수과목 . (이런 식으로 특정 쿼리qqq , 그냥 반환은Pre [ q [ 0 ] ] [ q [ 1 ] ] isPre[q[0]][q[1]] 입니다.i s Pre [ q [ 0 ]] [ q [ 1 ]] 일 수 있음)
토폴로지 정렬에서 thisCourse가 nextCourse의 선수과목으로 판단되면 thisCourse의 선수과목은 모두 nextCourse의 선수과목이 된다 . 수식으로 표현하면 다음과 같습니다.
∀ 0 ≤ i ≤ num Courses , is P re [ i ] [ 다음 C ourse ] ∣ = is P re [ i ] [ this C ourse ] \forall 0\leq i\leq numCourses,\ \ isPre[i][ 다음 강좌]\ \ |=\ isPre[i][이 강좌]∀0≤나≤n u m 강좌 수 , _ _ i s Pre [ i ] [ n e x tC o u rse ] ∣ _ = i s Pre [ i ] [ 이 강좌 ] _ _ _ _ _ _
- 시간 복잡도 O ( num 코스 2 + n + q ) O(numCourses^2 + n + q)O ( 개수 강좌 _ _ _ _ _ _2+N+q ) , 여기서nnn 은 전제 코스 관계 계수,qqq 는 쿼리 수입니다.
- 공간 복잡성 O ( num 코스 2 + n ) O(numCourses^2 + n)O ( 개수 강좌 _ _ _ _ _ _2+엔 )
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