< All posts

210. Course Schedule II

๋ฌธ์ œ ์„ค๋ช…

์ด ๋ฌธ์ œ์—์„œ๋Š” numCourses๊ฐœ์˜ ๊ฐ•์˜๊ฐ€ ์ฃผ์–ด์ง€๊ณ , ๊ฐ ๊ฐ•์˜์˜ ์„ ์ˆ˜๊ณผ๋ชฉ์ด ์ฃผ์–ด์งˆ ๋•Œ ๋ชจ๋“  ๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆœ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

210

ํ’€์ด ๋ฐ ํ•ด์„ค

๋”ฑ ๋ณด๋‹ˆ๊นŒ ์ด์ œ ์™œ ๊ทธ๋ž˜ํ”„ ๋ฌธ์ œ์ธ์ง€ ์•Œ ๊ฒƒ ๊ฐ™๋‹ค. ๋ญ”๊ฐ€ ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๊ณ  ๊ฐ„์„ ์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด์„œ, path๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ์œ ํ˜•์˜ ๋ฌธ์ œ๋ฉด ๋ณดํ†ต backtracking, DFS, ๋“ฑ์œผ๋กœ ์ ‘๊ทผํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

    1. ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ
    • ์„ ์ˆ˜๊ณผ๋ชฉ์„ ๊ฐ„์„ ์œผ๋กœ, ๊ฐ•์˜๋ฅผ ๋…ธ๋“œ๋กœ ํ•˜๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    1. DFS ๋ฐฑํŠธ๋ž˜ํ‚น ๊ตฌํ˜„
    • visited ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค:
      • 0: ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์Œ
      • 1: ๋ฐฉ๋ฌธ ์ค‘
      • 2: ๋ฐฉ๋ฌธ ์™„๋ฃŒ
    1. ๊ทธ๋ž˜ํ”„์—์„œ ์ˆœํ™˜ ๋ฃจํ”„๋‚˜ ๊ฒฝ๋กœ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธ
    • ๊ฐ ๊ฐ•์˜์— ๋Œ€ํ•ด DFS๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ˆœํ™˜ ๋ฃจํ”„๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
    • ๋งŒ์•ฝ ์ˆœํ™˜ ๋ฃจํ”„๊ฐ€ ๋ฐœ๊ฒฌ๋˜๋ฉด ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋ชจ๋“  ๊ฐ•์˜๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋ฉด ์ˆ˜๊ฐ• ์ˆœ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

ํ’€์ด

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        # 1) create graph
        graph = defaultdict(list)
        for course,prereq in prerequisites:
            graph[prereq].append(course)
        
        visited = [0] * numCourses
        order = []
        
        # 2) DFS backtracking
        def dfs(course):
            if visited[course] == 1:
                return False
            if visited[course] == 2:
                return True
            
            visited[course] = 1
            for neighbor in graph[course]:
                if not dfs(neighbor):
                    return False
            visited[course] = 2
            order.append(course)
            return True
        
        # 3) find path
        for course in range(numCourses):
            if visited[course] == 0:
                if not dfs(course):
                    return []
        
        return order[::-1]

Complexity Analysis

c

์‹œ๊ฐ„ ๋ณต์žก๋„

  • ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ: O(E)
  • DFS ํƒ์ƒ‰: O(V + E)
  • ์ „์ฒด ์‹œ๊ฐ„ ๋ณต์žก๋„: O(V + E)
  • ์—ฌ๊ธฐ์„œ V๋Š” ๊ฐ•์˜ ์ˆ˜(numCourses), E๋Š” ์„ ์ˆ˜๊ณผ๋ชฉ(prerequisites)์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค.

๊ณต๊ฐ„ ๋ณต์žก๋„

  • ๊ทธ๋ž˜ํ”„ ์ €์žฅ: O(E)
  • ์žฌ๊ท€ ํ˜ธ์ถœ ์Šคํƒ: O(V)
  • ์ „์ฒด ๊ณต๊ฐ„ ๋ณต์žก๋„: O(V + E)

Constraint Analysis

Constraints:
1 <= numCourses <= 2000
0 <= prerequisites.length <= numCourses * (numCourses - 1)
prerequisites[i].length == 2
0 <= ai, bi < numCourses
ai != bi
All the pairs [ai, bi] are distinct.

References

ยฉ 2025 HyunJoon Sung. All Rights Reserved.

GitHub