@@ -56,3 +56,104 @@ def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
5656 queue .append (neighbor )
5757
5858 return completed == numCourses
59+
60+ """
61+ ์์ ์ ๋ ฌ์ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ
62+ 1. DFS ๊ธฐ๋ฐ (์คํ์ ์์ ๋ค์ง๋ ๋ฐฉ์)
63+ 2. Kahn ์๊ณ ๋ฆฌ์ฆ (์ง์
์ฐจ์ 0๋ถํฐ ์ฐจ๋ก๋ก ํ ์ฒ๋ฆฌ)
64+
65+ Kahn ์๊ณ ๋ฆฌ์ฆ์ด๋?
66+ ๋ฐฉํฅ ๊ทธ๋ํ์์ ์ง์
์ฐจ์(indegree)๊ฐ 0์ธ ์ ์ ๋ถํฐ ์ฐจ๋ก๋ก ์ ๊ฑฐ(ํ์ ๋ฃ์ด ๊บผ๋ด๊ธฐ)ํ๋ฉฐ ์์ ์์๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ.
67+ ์ง์
์ฐจ์๊ฐ 0์ธ ์ ์ ์ด ํ๋๋ ์๋๋ฐ ์์ง ๋จ์ ์ ์ ์ด ์๋ค๋ฉด ์ฌ์ดํด ์กด์ฌ -> ์์ ์ ๋ ฌ ๋ถ๊ฐ.
68+
69+ ์์ ์์: ๋ฐฉํฅ ๊ทธ๋ํ์์ ๊ฐ์ (uโv)์ด ์๋ค๋ฉด, ์์์์ u๊ฐ ํญ์ v๋ณด๋ค ์์ ๋์ค๋ ์ ์ ๋ค์ ๋์ด.
70+ ์ง์
์ฐจ์: ์ ์ ์ผ๋ก ๋ค์ด์ค๋ ๊ฐ์ ์ ๊ฐ์.
71+
72+
73+ TC: O(V + E), V: ๊ณผ๋ชฉ ์, E: prerequisite ๊ด๊ณ ์
74+ SC: O(V + E), ๊ทธ๋ํ + ์ง์
์ฐจ์ ๋ฐฐ์ด
75+ """
76+ class Solution :
77+ def canFinish (self , numCourses : int , prerequisites : List [List [int ]]) -> bool :
78+ # 1) ๊ทธ๋ํ(์ธ์ ๋ฆฌ์คํธ)์ ์ง์
์ฐจ์ ๋ฐฐ์ด ๋ง๋ค๊ธฐ
79+ adj = [[] for _ in range (numCourses )]
80+ indeg = [0 ] * numCourses
81+ for a , b in prerequisites : # b -> a (b๋ฅผ ๋จผ์ ๋ค์ด์ผ a๋ฅผ ๋ค์ ์ ์์)
82+ adj [b ].append (a )
83+ indeg [a ] += 1
84+
85+ # 2) ์ง์
์ฐจ์ 0์ธ ์ ์ ๋ค๋ก ํ ์ด๊ธฐํ
86+ q = deque ([i for i in range (numCourses ) if indeg [i ] == 0 ])
87+ taken = 0 # ์ฒ๋ฆฌ(์๊ฐ) ์๋ฃํ ๊ณผ๋ชฉ ์
88+
89+ # 3) ํ์์ ๋นผ๋ฉฐ ๊ฐ์ ์ ๊ฑฐ(=ํ์ ๊ณผ๋ชฉ ์ง์
์ฐจ์ ๊ฐ์)
90+ while q :
91+ u = q .popleft ()
92+ taken += 1
93+ for v in adj [u ]:
94+ indeg [v ] -= 1
95+ if indeg [v ] == 0 :
96+ q .append (v )
97+
98+ # 4) ๋ชจ๋ ์ฒ๋ฆฌ๋์ผ๋ฉด ์ฌ์ดํด ์์
99+ return taken == numCourses
100+
101+
102+ """
103+ DFS ๊ธฐ๋ฐ
104+ TC: O(V + E), V: ๊ณผ๋ชฉ ์, E: prerequisite ๊ด๊ณ ์
105+ SC: O(V + E), ๊ทธ๋ํ + ํ์ ์ค์ธ ๊ณผ๋ชฉ ์งํฉ + ์๊ฐ ์๋ฃํ ๊ณผ๋ชฉ ์งํฉ
106+ """
107+ class Solution :
108+ def canFinish (self , numCourses : int , prerequisites : List [List [int ]]) -> bool :
109+ graph = {i : [] for i in range (numCourses )}
110+ for crs , pre in prerequisites :
111+ # ์ ์ ๊ณผ๋ชฉ์ ์์๋ก ์ถ๊ฐ
112+ graph [crs ].append (pre )
113+
114+ # ํ์์ค
115+ traversing = set ()
116+ # ์๊ฐ๊ฐ๋ฅํ ๊ณผ๋ชฉ
117+ finished = set ()
118+
119+ def can_finish (crs ):
120+ if crs in traversing :
121+ return False
122+ if crs in finished :
123+ return True
124+
125+ traversing .add (crs )
126+ for pre in graph [crs ]:
127+ if not can_finish (pre ):
128+ return False
129+ traversing .remove (crs )
130+ finished .add (crs )
131+ return True
132+
133+ for crs in graph :
134+ if not can_finish (crs ):
135+ return False
136+ return True
137+
138+ from functools import cache
139+
140+ # ์ค์ธ ์ฝ๋
141+ class Solution :
142+ def canFinish (self , numCourses : int , prerequisites : List [List [int ]]) -> bool :
143+ graph = {i : [] for i in range (numCourses )}
144+ for crs , pre in prerequisites :
145+ graph [crs ].append (pre )
146+
147+ traversing = set ()
148+
149+ @cache
150+ def can_finish (crs ):
151+ if crs in traversing :
152+ return False
153+
154+ traversing .add (crs )
155+ result = all (can_finish (pre ) for pre in graph [crs ])
156+ traversing .remove (crs )
157+ return result
158+
159+ return all (can_finish (crs ) for crs in graph )
0 commit comments