취미가 좋다

207. Course Schedule 본문

알고리즘 문제풀이/Leetcode

207. Course Schedule

benlee73 2021. 8. 24. 17:33

https://leetcode.com/problems/course-schedule/

 

Course Schedule - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

Solution

from queue import Queue

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        q = Queue()
        a2b = {} # a : 조건이 필요한 수업
        b2a = {} # b : 조건
        for a, b in prerequisites:
            if a==b:
                return False
            if a2b.get(a):
                a2b[a].append(b)
            else:
                a2b[a] = [b]
            if b2a.get(b):            
                b2a[b].append(a)
            else:
                b2a[b] = [a]

        for i in range(numCourses):
            if not a2b.get(i):
                q.put(i)

        while(not q.empty() and a2b):
            i = q.get()
            if not b2a.get(i):
                continue
            for j in b2a[i]:
                a2b[j].remove(i)
                if len(a2b[j]) == 0:
                    q.put(j)
                    del a2b[j]
        
        if len(a2b):
            return False
        return True
  • 큐와 두 개의 딕셔너리를 생성한다.
  • prerequisites를 보면서, 각 수업마다 필요한 조건과, 각 조건마다 딸려있는 수업들을 저장한다.
  • 조건 없는 수업들을 큐에 넣는다.
  • 큐에서 하나씩 꺼내가며, 그것을 조건으로 가지고 있는 수업들의 조건들을 하나씩 만족시켜간다.
  • 그 때 수업의 모든 조건이 만족하면 딕셔너리에서 없애고 큐에 넣는다.
  • 큐에서 꺼낼 수업이 없거나, 모든 조건을 만족했을 때 while문을 종료한다.
  • 만족해야할 조건이 더 남았다면 False를 반환한다.

Another

class Solution(object):
    def canFinish(self, numCourses, prerequisites):
        graph = [[] for _ in range(numCourses)]
        for x, y in prerequisites:
            graph[x].append(y)
            
        visited = [0 for _ in range(numCourses)]

        for i in range(numCourses):
            if not self.dfs(graph, visited, i):
                return False
        return True
    
    def dfs(self, graph, visited, i):
        if visited[i] == -1:
            return False
        if visited[i] == 1:
            return True
            
        visited[i] = -1

        for j in graph[i]:
            if not self.dfs(graph, visited, j):
                return False

        visited[i] = 1
        return True
  • cycle이 있으면 모든 수업을 들을 수 없으므로, False를 반환해야 한다.
  • 방향은 상관 없이 cycle만 없으면 된다.
  • dfs로 들린 i에 해당한 visited를 -1을 넣어서 방문했음을 나타낸다.
  • 그 아래 노드들로 계속 방문한다.
  • 연결된 그래프를 따라 가다가 -1이 나오면 이미 들린 곳이므로 False를 반환한다.
  • 하위 노드를 다 들렸을 때 False를 한번도 발견하지 않은 노드는 1을 넣는다.
  • 연결된 그래프를 따라 가다가 1을 만나면, 아래는 다 괜찮다는 뜻이므로 True를 반환한다.

 

  • 의문이 드는 점은 아래의 상황이다. 이런 상황에서는 모든 수업을 수강할 수 있으므로, -1을 만나더라도 예외처리해야하는 것이 아닐까? 이런 상황은 예시에 나오지 않았나보다.

queue

from queue import Queue

q = Queue()

q.put(1)
print(q.qsize()) 		# 1
a = q.get() 			# a = 1
if q.empty():
	print('is empty') 	# is empty
    
'''
q.put()
q.qsize()
q.get()
q.empty()
'''

python에서 queue의 기본 사용법이다.

 

'알고리즘 문제풀이 > Leetcode' 카테고리의 다른 글

210. Course Schedule II  (0) 2021.08.31
208. Implement Trie (Prefix Tree)  (0) 2021.08.30
200. Number of Islands  (0) 2021.08.20
199. Binary Tree Right Side View  (0) 2021.08.17
198. House Robber  (0) 2021.08.16
Comments