(Leetcode) [Graph] Course schedule
Question
๋ํ๊ต ์๊ฐ์ ์ฒญ์ ์์๋ก ๋ ๋ฌธ์ ์ด๋ค.
int numCourses: number of courses you have to take
vector
Approach
Consider this problem as a graph.
e.g. if course u
is a prerequisite of course v
, add a directed edge from node u
to node v
.
If a cycle is detected in the graph, then it is not possible to finish all courses.
How to detect cycle in a directed graph?
Use DFS (Depth First Search). DFS for a connected graph produces a tree.
If there is a back edge
(self-loop or node to one if its ancestors) present in the graph, there is a cycle in a graph.
DFS (Depth First Search)
DFS is an algorithm for traversing or searching tree or graph data structures.
Basic idea: start from the root/any arbiytrary node, mark the node and move to the adjacent unmarked node and continue this loop until there is no unmarked adjacent node.
DFS๋ ๋ง ๊ทธ๋๋ก ๊น์ด ์ฐ์ ํ์์ด๋ค.
๊ทธ๋ํ ์์ ์กด์ฌํ๋ ์์์ ํ ์ ์ ์ผ๋ก๋ถํฐ ์ฐ๊ฒฐ๋์ด ์๋ ํ ์ ์ ์ผ๋ก๋ง ๋์๊ฐ๋ค๋ผ๋ ๋ฐฉ๋ฒ์ ์ฐ์ ์ผ๋ก ์ ํํ๋ค. ์ฐ๊ฒฐํ ์ ์๋ ์ ์ ์ด ์์ ๋๊น์ง ๊ณ์ ์ฐ๊ฒฐํ๋ค๊ฐ๊ฐ ๋์ด์ ์ฐ๊ฒฐ๋์ง ์์ ์ ์ ์ด ์์ผ๋ฉด ๋ฐ๋ก ๊ทธ ์ ๋จ๊ณ์ ์ ์ ์ผ๋ก ๋์๊ฐ์ ์ฐ๊ฒฐํ ์ ์๋ ์ ์ ์ด ์๋์ง ์ดํด๋ณธ๋ค.
์๋ฃ๊ตฌ์กฐ๋ stack
์ ์ด์ฉํ๋ค.
Time Complexity: O(V+E), where V=number of vertices, E=number of edges.
Algorithm of DFS
Use of recursive function.
Required features: index of the node and a visited array.
- Mark the current node as visited.
- Traverse all the adjacent and unmarked nodes and call recursive function with the index of the adjacent node.
class Graph {
public:
map<int, bool> visited;
map<int, vector<int>> adj;
void addEdge(int v, int w) {
adj[v].push_back(w); // add w to v's list (edge from v to w)
}
void DFS(int v) {
// return false if it meets a node which was visited (cycle is detected)
// if (visited[v]==true)
// return false;
// mark the current node as visited
visited[v] = true;
cout << v << " ";
// recur for all the vertices adjacent to this vertex
vector<int>::iterator i;
for (i=adj[v].begin(); i != adj[v].end(); i++) {
if (!visited[*i]) {
DFS(*i);
}
}
}
}
Solution
๊ทธ๋ํ์์ cycle์ด ๋ฐ๊ฒฌ๋๋ฉด false, ์๋๋ฉด true.
- Create a unordered map with key: course, value: list of adjacent nodes.
- Use vector
visited
to record all the visited nodes. - ์ค๊ฐ์ false๊ฐ ํ๋๋ผ๋ ๋์ค๋ฉด dfs ํจ์ ์์ ์๋ for loop์ ์ธํด์ ์ฐ์์ผ๋ก false๊ฐ ๋์ค๊ธฐ ๋๋ฌธ์ returns false.
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
unordered_map<int, vector<int>> adjacencyList(numCourses);
vector<int> visited(numCourses, 0);
// vector<int> visited;
// make list of prerequisites of all courses and add to a map.
for (int i=0; i<prerequisites.size(); i++) {
adjacencyList[prerequisites[i][0]].push_back(prerequisites[i][1]);
}
// since there may be more than one graph, loop is required.
for (int i=0; i<numCourses; i++) {
if (!dfs(i, adjacencyList, visited))
return false;
}
return true;
}
bool dfs(int course, unordered_map<int, vector<int>>& adjacencyList, vector<int> visited) {
// return false if the node is already visited
if (visited[course]==1)
return false;
// if (find(visited.begin(), visited.end(), course) != visited.end())
// return false;
if (adjacencyList[course].size()==0)
return true;
visited[course]=1; // mark node as visiting
// visited.push_back(course);
for (int i=0; i<adjacencyList[course].size(); i++) {
if (!dfs(adjacencyList[course][i], adjacencyList, visited))
return false;
}
// visited.pop_back();
adjacencyList[course] = {};
return true;
}
Runtime
์ ํ๋ธ์ neetcode๋ผ๋ ์ฑ๋์ ์ฌ๋ผ์จ ํ์ด๋ฅผ ๋ดค์๋ visited๋ผ๋ list์ ๋ฐฉ๋ฌธํ๊ณ ์๋ ๋
ธ๋๋ฅผ ์ถ๊ฐํ๊ณ ๋ฃ๊ณ ํ๊ธธ๋ vector push_back๊ณผ pop_back์ ์ด์ฉํด์ ์ถ๊ฐํ๊ณ ๋ฃ๋ ๋ฐฉ์ ํ๋์, ๊ทธ๋ฅ 0์ผ๋ก ์ด๊ธฐํ๋ numCourses ์ฌ์ด์ฆ์ vector๋ฅผ ์ด์ฉํด์ ๋ฐฉ๋ฌธํ๊ณ ์๋ ๋
ธ๋๋ฅผ 1๋ก ๋ฐ๊ฟ์ฃผ๋ ๋ฐฉ์ ํ๋๋ฅผ ํ
์คํธ ํด๋ณด์๋ค.
๊ทธ ๊ฒฐ๊ณผ ๋ฃ๊ณ ๋นผ๋ ๋ฐฉ์์ด runtime์ด ์กฐ๊ธ ๋ ๊ธฐ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ฐํ ๋ ์ก์๋จน๋๋ค.
์ฝ๋ฉํธ
์๊ฐ์ ๋๋ฌด ์ค๋ ์ก์๋จน์๋ค. ์ฝ์ง์ ๋๋ฌด ๋ง์ด ํ๋ค. ํ์คํ ์ฒ์ ๋ฐฐ์ฐ๋ DFS๋ผ๋ ๊ฐ๋ ์ด๋ผ ๊ทธ๋ ๊ธฐ๋ ํ๊ณ , ์ง์ค๋ ฅ๋ ํํธ๋ฌ์ก๋ค. ์ผ๋ฅธ ๋ค์ ๋ฌธ์ ๋ก ๋์ด๊ฐ์ผ๊ฒ ๋ค.
References
https://www.geeksforgeeks.org/find-whether-it-is-possible-to-finish-all-tasks-or-not-from-given-dependencies/
https://www.youtube.com/watch?v=EgI5nU9etnU
Leave a comment