[JS] Course Schedule

2022. 10. 9. 13:53

🔒 문제 (LeetCode 207)

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

  • For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.

Return true if you can finish all courses. Otherwise, return false.

Constraints:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • All the pairs prerequisites[i] are unique.

 

🌊 입출력

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

 


 

🔑 해결

🌌 알고리즘

위상정렬 (Topology Sort) - 큐

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function(numCourses, prerequisites) {
    const inDegrees = new Array(numCourses).fill(0)
    for(const [course] of prerequisites) {
        inDegrees[course]++
    }
    
    const q = []
    for(let i = 0; i < inDegrees.length; i++) {
        if(!inDegrees[i]) q.push(i)
    }
    
    const result = []
    while(q.length) {
        const cur = q.shift()
        numCourses--
        
        for(const [course, pre] of prerequisites) {
            if(cur === pre) {
                inDegrees[course]--
                if(!inDegrees[course]) q.push(course)
            }
        }
    }
    
    return !numCourses ? true : false
};

DFS - 재귀함수

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function(numCourses, prerequisites) {
    const map = new Map()   // key:코스 - value: key의 선행 코스 배열
    const visited = new Set()
    
    for(let i = 0; i < numCourses; i++) map.set(i, [])
    for(let [course, pre] of prerequisites) {
        map.get(course).push(pre)
    }
    
    const dfs = (course) => {
        // 이전에 선택했던 코스일 경우 같은 사이클에 해당되므로 false 반환
        if(visited.has(course)) return false
        
        // 선행 코스가 없거나 모두 완료한 경우 true 반환
        if(map.get(course).length === 0) return true
        
        visited.add(course)
        for(const pre of map.get(course)) {
            // 해당 코스에 필요한 선행 코스 모두 완료해야 가능
            if(!dfs(pre)) return false
        }
        visited.delete(course)
        map.set(course, []) // 코스 완료 표시
        
        return true
    }
   
    for(let i = 0; i < numCourses; i++) {
        if(!dfs(i)) return false
    }
    
    return true
};

'코딩테스트 (JS) > DFS | BFS' 카테고리의 다른 글

[JS] Longest Increasing Path in a Matrix  (0) 2022.10.14
[JS] Course Schedule II  (0) 2022.10.09
[JS] Pacific Atlantic Water Flow  (0) 2022.10.07
[JS] Word Search  (0) 2022.09.02
[JS] Generate Parentheses  (0) 2022.09.01

+ Recent posts