본문 바로가기
Algorithm/파이썬 알고리즘 인터뷰

[그래프] 코스 스케줄

by 밤초록 2022. 3. 4.
207 |  Course Schedule
https://leetcode.com/problems/course-schedule/

 

 

 

이상 코드

 

DFS로 순환 구조 판별

 

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        graph = collections.defaultdict(list)
        # 그래프 구성
        for x, y in prerequisites:
            graph[x].append(y)

        traced = set()

        def dfs(i):
            # 순환 구조이면 False
            if i in traced:
                return False

            traced.add(i)
            for y in graph[i]:
                if not dfs(y):
                    return False
            # 탐색 종료 후 순환 노드 삭제
            traced.remove(i)

            return True

        # 순환 구조 판별
        for x in list(graph):
            if not dfs(x):
                return False

        return True

 

  • graph[완료하고 싶은 코스] = [끝내야하는 코스들]
  • for x in list(graph)로 도는 이유 : defaultdict 이기 때문 -> list로 묶어서 해결

 

 

가지치기를 이용한 최적화

 

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        graph = collections.defaultdict(list)
        # 그래프 구성
        for x, y in prerequisites:
            graph[x].append(y)

        traced = set()
        visited = set()

        def dfs(i):
            # 순환 구조이면 False
            if i in traced:
                return False
            # 이미 방문했던 노드이면 True
            if i in visited:
                return True

            traced.add(i)
            for y in graph[i]:
                if not dfs(y):
                    return False
            # 탐색 종료 후 순환 노드 삭제
            traced.remove(i)
            # 탐색 종료 후 방문 노드 추가
            visited.add(i)

            return True

        # 순환 구조 판별
        for x in list(graph):
            if not dfs(x):
                return False

        return True

 

  • 한 번 방문한 그래프 두 번 이상 방문하지 않도록 무조건 True return 
  • 1번 방법보다 10배 빠름
반응형

댓글