Skip to content

Commit 2d9d741

Browse files
committed
🚀 19-Jul-2020
1 parent da7faf2 commit 2d9d741

File tree

3 files changed

+229
-1
lines changed

3 files changed

+229
-1
lines changed

algorithms/graph/topological_sorting.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ vector<int> topoSort(int V, vector<int> adj[]) {
113113
vector<bool> vis(V, false);
114114
for(int i=0;i<V;i++){
115115
if(!vis[i])
116-
dfs(adj, 0, vis);
116+
dfs(adj, i, vis);
117117
}
118118
vector<int>res;
119119
while(!s.empty()){
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
There are a total of n courses you have to take, labeled from 0 to n-1.
2+
3+
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
4+
5+
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
6+
7+
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
8+
9+
Example 1:
10+
11+
Input: 2, [[1,0]]
12+
Output: [0,1]
13+
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
14+
course 0. So the correct course order is [0,1] .
15+
Example 2:
16+
17+
Input: 4, [[1,0],[2,0],[3,1],[3,2]]
18+
Output: [0,1,2,3] or [0,2,1,3]
19+
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
20+
courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
21+
So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
22+
Note:
23+
24+
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
25+
You may assume that there are no duplicate edges in the input prerequisites.
26+
Hide Hint #1
27+
This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
28+
Hide Hint #2
29+
Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
30+
Hide Hint #3
31+
Topological sort could also be done via BFS.
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
class Solution {
46+
public:
47+
48+
stack<int> s;
49+
50+
void dfs(vector<int> adj[],int node, vector<bool> &vis){
51+
vis[node]=true;
52+
for(auto x: adj[node]){
53+
if(!vis[x])
54+
dfs(adj, x, vis);
55+
}
56+
s.push(node);
57+
}
58+
59+
vector<int> topoSort(int V, vector<int> adj[]) {
60+
vector<bool> vis(V, false);
61+
for(int i=0;i<V;i++){
62+
if(!vis[i])
63+
dfs(adj, i, vis);
64+
}
65+
vector<int>res;
66+
while(!s.empty()){
67+
res.push_back(s.top());
68+
s.pop();
69+
}
70+
return res;
71+
}
72+
73+
bool detectCycleUtil(vector<int>adj[], int node, vector<bool> &vis, vector<bool> &rec){
74+
if(!vis[node]){
75+
vis[node]=true;
76+
rec[node]=true;
77+
}
78+
for(auto x: adj[node]){
79+
if(!vis[x] && detectCycleUtil(adj, x, vis, rec)) return true;
80+
else if(rec[x]==true) return true;
81+
}
82+
rec[node]=false;
83+
return false;
84+
}
85+
86+
bool detectCycle(int V, vector<int> adj[]){
87+
vector<bool> vis(V, false);
88+
vector<bool> rec(V, false);
89+
90+
for(int i=0;i<V;i++){
91+
if(!vis[i]){
92+
if(detectCycleUtil(adj, i, vis, rec)) return true; // cycle exists
93+
}
94+
}
95+
return false;
96+
}
97+
98+
99+
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
100+
vector<int> adj[numCourses];
101+
int n=prerequisites.size();
102+
for(int i=0;i<n;i++){
103+
int u=prerequisites[i][1];
104+
int v=prerequisites[i][0];
105+
adj[u].push_back(v);
106+
}
107+
108+
vector<int> res;
109+
110+
if(detectCycle(numCourses, adj)) return res; // not a DAG
111+
112+
res=topoSort(numCourses, adj);
113+
return res;
114+
115+
}
116+
};
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
There are a total of n courses you have to take, labeled from 0 to n-1.
2+
3+
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
4+
5+
Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
6+
7+
There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
8+
9+
Example 1:
10+
11+
Input: 2, [[1,0]]
12+
Output: [0,1]
13+
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
14+
course 0. So the correct course order is [0,1] .
15+
Example 2:
16+
17+
Input: 4, [[1,0],[2,0],[3,1],[3,2]]
18+
Output: [0,1,2,3] or [0,2,1,3]
19+
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
20+
courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
21+
So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
22+
Note:
23+
24+
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
25+
You may assume that there are no duplicate edges in the input prerequisites.
26+
27+
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
class Solution {
42+
public:
43+
44+
stack<int> s;
45+
46+
void dfs(vector<int> adj[],int node, vector<bool> &vis){
47+
vis[node]=true;
48+
for(auto x: adj[node]){
49+
if(!vis[x])
50+
dfs(adj, x, vis);
51+
}
52+
s.push(node);
53+
}
54+
55+
vector<int> topoSort(int V, vector<int> adj[]) {
56+
vector<bool> vis(V, false);
57+
for(int i=0;i<V;i++){
58+
if(!vis[i])
59+
dfs(adj, i, vis);
60+
}
61+
vector<int>res;
62+
while(!s.empty()){
63+
res.push_back(s.top());
64+
s.pop();
65+
}
66+
return res;
67+
}
68+
69+
bool detectCycleUtil(vector<int>adj[], int node, vector<bool> &vis, vector<bool> &rec){
70+
if(!vis[node]){
71+
vis[node]=true;
72+
rec[node]=true;
73+
}
74+
for(auto x: adj[node]){
75+
if(!vis[x] && detectCycleUtil(adj, x, vis, rec)) return true;
76+
else if(rec[x]==true) return true;
77+
}
78+
rec[node]=false;
79+
return false;
80+
}
81+
82+
bool detectCycle(int V, vector<int> adj[]){
83+
vector<bool> vis(V, false);
84+
vector<bool> rec(V, false);
85+
86+
for(int i=0;i<V;i++){
87+
if(!vis[i]){
88+
if(detectCycleUtil(adj, i, vis, rec)) return true; // cycle exists
89+
}
90+
}
91+
return false;
92+
}
93+
94+
95+
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
96+
vector<int> adj[numCourses];
97+
int n=prerequisites.size();
98+
for(int i=0;i<n;i++){
99+
int u=prerequisites[i][1];
100+
int v=prerequisites[i][0];
101+
adj[u].push_back(v);
102+
}
103+
104+
vector<int> res;
105+
106+
if(detectCycle(numCourses, adj)) return res; // not a DAG
107+
108+
res=topoSort(numCourses, adj);
109+
return res;
110+
111+
}
112+
};

0 commit comments

Comments
 (0)