문제 링크: https://leetcode.com/problems/course-schedule-ii/
들을 수 있는 수업의 개수인 numCourses가 주어지고, 선수 과목 쌍이 주어지면, 모든 수업을 수강할 수 있는지 그 여부를 반환하는 문제이다.
즉, 그래프가 DAG(Directed Acyclie Graph)인지 판단하는 문제이며, cycle의 존재 여부를 판단하는 문제로 치환할 수 있다.
즉, 방향이 있는 그래프에서 cycle이 있다면 false, 없고 모든 노드를 방문할 수 있다면 true를 반환하는 문제로 치환할 수 있고, 바로 위상정렬을 하는 문제이다.
'순서가 정해져 있는' 작업을 차례로 수행해야 할 때, 그 순서를 결정하는 알고리즘이다.
위상정렬을 사용하면 방향 그래프에서 다양한 조건들이 얽혀있을 때 일직선 상의 한 가지 경로를 찾아낼 수 있다.
결과: 모든 원소를 방문 했다면 큐에서 꺼낸 결과가 위상정렬 결과 (모든 원소 방문 전 큐가 비었다면 사이클이 존재)
class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
List<List<Integer>> adjacencyList = new ArrayList<>();
Queue<Integer> queue = new LinkedList<>();
int[] result = new int[numCourses];
int[] indegree = new int[numCourses];
for(int i=0; i<numCourses; i++) {
adjacencyList.add(new ArrayList<>());
}
for(int course[] : prerequisites) {
int prevCourse = course[1];
int nextCourse = course[0];
adjacencyList.get(prevCourse).add(nextCourse);
indegree[nextCourse]++;
}
for(int course=0; course<numCourses; course++) {
if(indegree[course]==0) {
queue.offer(course);
}
}
int resultIndex = 0;
while(!queue.isEmpty()) {
Integer currCourse = queue.poll();
result[resultIndex++] = currCourse;
for(int course: adjacencyList.get(currCourse)) {
indegree[course]--;
if(indegree[course] == 0) {
queue.offer(course);
}
}
}
if(resultIndex != numCourses) return new int[]{};
return result;
}
}