Topological Sorting
Topological Sorting is based on graph searching, take leetcode below as example to learn the steps to solve a Topological Sorting related algorithmn
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 course bi first if you want to take course ai.
For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1. Return true if you can finish all courses. Otherwise, return false.
Example 1:
Input: numCourses = 2, prerequisites = [[1,0]] Output: true Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. Example 2:
Input: numCourses = 2, prerequisites = [[1,0],[0,1]] Output: false Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
step1: whether it is a Directed Acyclic Graphpic
step1.1: build graphic
List<Integer> buildGraph(int num, int[][] prerequisites) {
// the number of nodes. numCourses = 2, prerequisites = [[1,0],[0,1]]
List<Integer>[] graph = new LinkedList[num];
for (int i = 0; i < num; i++) {
graph[i] = new LinkedList<>(); // graph[0], graph[1]
}
// build edge
for (int[] edge : preprequisites) {
// edge = [1,0], edge = [0,1]
int from = edge[1]; // edge[1] = 0, egde[1] = 1;
int to = edge[0]; //edge[0] = 1, edge[0] = 0;
graph[from].add(to); // graph[0].add(1); //graph[0] = [1, 0]; graph[1] = [1, 0];
}
return graph;
}
step1.2: DFS to traverse
boolean[] visited;
boolean canFinish(int num, int[][] prerequisites) {
// the number of nodes. numCourses = 2, prerequisites = [[1,0],[0,1]]
List<Integer>[] graph = buildGraph(num, prerequisites);
visited = new boolean[num];
for (int i = 0; i < num; i++) {
traverse(graph, i); // graph[0], graph[1]
}
}
void traverse(List<Integer>[] graph, int s) {
if (visited[s]) {
return;
}
visited[s] = true;
for (int t : graph[s]) {
traberse(graph, t);
}
}
step1.3: record the traverse path
boolean[] onPath;
boolean hasCycle = false;
boolean[] visited;
void traverse(List<Integer>[] graph, int s) {
if (onPath(s)) {
hasCycle = true;
}
if (visited[s]) {
return;
}
visited[s] = true;
onPath[s] = true;
for (int t : graph[s]) {
traberse(graph, t);
}
onPath[s] = false;
}