코딩 테스트 (Python)/리트코드
[리트코드] 207. 코스 스케쥴 (Python)
hihyuk
2024. 1. 11. 12:39
Course Schedule - LeetCode
Can you solve this real interview question? Course Schedule - 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 co
leetcode.com
문제
들어야 할 총 강좌의 개수가 주어지고 그와 관련된 배열이 주어질 때 모든 과정을 이수할 수 있다면 True 아니라면 False를 출력해라.
과정
- 강좌의 개수와 전제 조건이 주어진다.
- [a, b] 형태로 주어지는데 이는 a라는 강좌를 듣기 위해서는 b라는 강좌를 반드시 들어야 한다는 뜻이다.
- ex) [1, 0] 이 주어진다면 1 강좌를 듣기 위해서 0을 받드시 이수해야한다는 뜻이다.
만약 [1,0] , [0,1] 이 주어진다면 1을 듣기위해서는 0을 반드시 이수해야하고 0을 듣기 위해서는 1을 반드시 이수해야 하기 때문에 모순이 발생한다. 따라서 False를 반환한다.
입력
numCourses = 2, prerequisites = [[1,0]]
출력
True
풀이
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
graph = [[] for _ in range(numCourses)]
for a, b in prerequisites:
graph[a].append(b)
visited = [0] * numCourses
def dfs(i):
if visited[i] == 1:
return False
if visited[i] == 2:
return True
visited[i] = 1
for n in graph[i]:
if not dfs(n):
return False
visited[i] = 2
return True
for i in range(numCourses):
if visited[i] == 0 and not dfs(i):
return False
return True
한 줄씩 코드 해석해보기
graph = [[] for _ in range(numCourses)]
for a, b in prerequisites:
graph[a].append(b)
- 그래프 리스트를 만들어주고 입력 받은 numCourses의 개수만큼 리스트를 넣어준다.
- 그 후 전제 조건에서 입력된 [a,b]의 값을 graph 인덱스 a에 b를 추가하는 식으로 넣어준다.
visited = [0] * numCourses
- 방문한 인덱스를 체크하기 위한 visited 변수에 [0]을 numCourses 개수만큼 넣어준다.
- 방문을 아직 하지 않았다면 0으로 표시한다.
def dfs(i):
if visited[i] == 1:
return False
if visited[i] == 2:
return True
- dfs함수를 정의해준다.
- 만약 입력받은 i 번째 위치의 visited리스트의 값이 1이면 False를 return한다.
- 즉, 방문 중이라면 1을 표시한다.
- 2라면 True를 return한다. 이미 방문을 했다면 2로 표시한다.
visited[i] = 1
for n in graph[i]:
if not dfs(n):
return False
visited[i] = 2
return True
- 첫번째 탐색의 경우 우선 visited 변수값을 1로 업데이트 해준다. (방문 중)
- 그후 그래프에서 인접한 값들을 탐색한다.
- 만약 dfs 함수를 통해 방문한 값이 1이라면 원형 사이클을 이루기 때문에 False를 return한다.
- 모든 방문이 끝나면 visited[i]의 값을 2로 바꾸어 준다. (방문 처리)
- 만약 방문한 값이 2라면 이미 방문한 값이기 때문에 True를 return 해준다.
for i in range(numCourses):
if visited[i] == 0 and not dfs(i):
return False
return True
- numCourses의 개수만큼 for문을 돌려준다
- 만약 탐색하는 중에 visited[i] 값이 0 이고 dfs함수에서 원형 사이클이 발견되었다면 바로 False를 return해준다.
- 위 모든 경우가 해당하지 않는다면 True를 return하고 종료한다.