Problem
Analysis Process
When we use a queue for breadth first search, all the nodes with an entry degree of 0 are placed in the queue, they are the first nodes that can be ordered topologically, and the relative order between them is irrelevant
In each step of breadth first search, we extract the node u at the head of the queue
We put u in the answer; we remove all the outsides of u, so we reduce the input-degree of all the adjacent nodes of u by 1 if the input-degree of one of the adjacent nodes v goes to 0, then we put the v in the queue
If these n nodes are included in the answer at the end of the breadth first search, then we have found a topological sort. Otherwise, it means that there is a ring in the graph, so there is no topological sort
Code
golang
func findOrder(numCourses int, prerequisites [][]int) []int {
//There are a number of pre-semester courses in this course
inDegree := make([]int, numCourses)
//Make a list to record which courses are in advance of the course
outEdge := make([][]int, numCourses)
//ResultSet
res := []int{}
for i:=0; i<len(prerequisites); i++ {
// update
inDegree[prerequisites[i][0]]++
outEdge[prerequisites[i][1]] = append(outEdge[prerequisites[i][1]], prerequisites[i][0])
}
//The queue is used to record courses with a zero degree of entry
queue := []int{}
for i:=0; i<numCourses; i++ {
if inDegree[i] == 0 {
queue = append(queue, i)
}
}
//There are no classes that do not depend on other classes. Return null
if len(queue) == 0 {
return res
}
for len(queue) > 0 {
// Take out the header and add to the result set
node := queue[0]
queue = queue[1:]
res = append(res, node)
// Deal with the outgoing side of the team head, and bring in the team with the incoming degree of 0
for i:=0; i<len(outEdge[node]); i++ {
out := outEdge[node][i]
inDegree[out]--
if inDegree[out] == 0 {
queue = append(queue, out)
}
}
}
//Check to see if all classes are scheduled. If not, there is a ring. Cannot be scheduled. Return empty
if len(res) == numCourses {
return res
}
return []int{}
}
java
class Solution {
// Store directed graphs
List<List<Integer>> edges;
// Store the degree of entry for each node
int[] indeg;
// Store the answers
int[] result;
// The subscript
int index;
public int[] findOrder(int numCourses, int[][] prerequisites) {
edges = new ArrayList<List<Integer>>();
for (int i = 0; i < numCourses; ++i) {
edges.add(new ArrayList<Integer>());
}
indeg = new int[numCourses];
result = new int[numCourses];
index = 0;
for (int[] info : prerequisites) {
edges.get(info[1]).add(info[0]);
++indeg[info[0]];
}
Queue<Integer> queue = new LinkedList<Integer>();
// Put all the nodes with an entry degree of 0 into the queue
for (int i = 0; i < numCourses; ++i) {
if (indeg[i] == 0) {
queue.offer(i);
}
}
while (!queue.isEmpty()) {
// Take a node from the head of the queue
int u = queue.poll();
// Put it in the key
result[index++] = u;
for (int v: edges.get(u)) {
--indeg[v];
// If the entry degree of adjacent node V is 0, then the course corresponding to V can be selected
if (indeg[v] == 0) {
queue.offer(v);
}
}
}
if (index != numCourses) {
return new int[0];
}
return result;
}
}