## subject

Topic link: https://leetcode-cn.com/problems/course-schedule-ii

Now you have a total of N courses to choose, which are 0 to n-1.

Some prerequisite courses are required before taking some courses. For example, to learn lesson 0, you need to complete lesson 1 first. We use a match to represent them: [0,1]

Given the total number of courses and their prerequisites, return to the order in which you have arranged to complete all courses.

There may be multiple correct orders, you just need to return one. If it is not possible to complete all courses, an empty array is returned.

Example 1: Input: 2, [[1,0]] Output: [0,1] Explanation: there are 2 courses in total. To learn Lesson 1, you need to complete lesson 0 first. Therefore, the correct course order is [0,1].

Example 2: Input: 4, [[1,0], [2,0], [3,1], [3,2]] Output: [0,1,2,3] or [0,2,1,3] Explanation: there are 4 courses in total. To learn Lesson 3, you should first complete lesson 1 and lesson 2. And course 1 and course 2 should both come after course 0. Therefore, a correct course sequence is [0,1,2,3]. Another correct sort is [0,2,1,3].

explain: The prerequisite for input is a graph represented by an edge list, not an adjacency matrix. Please refer to the representation of the figure for details. You can assume that there are no duplicate edges in the input prerequisites.

Tips: This problem is equivalent to finding out whether a loop exists in a digraph. If there is a loop, there is no topological ordering, so it is impossible to select all courses for learning. Topology sorting through DFS - a wonderful video tutorial about Coursera (21 minutes), which introduces the basic concepts of topology sorting. Topology sorting can also be done through BFS.

## Penetration

Baidu Encyclopedia explains as follows

- When the degree of penetration is 0, the point in the digraph is not the end point of any edge, that is to say, the edge connected by this point takes this point as the starting point.
- In the topological sorting of digraphs, every time a point with a degree of entry of 0 is selected to join the topological queue, and then all the edges connected with this point are deleted.

## Problem solving record

- Limited statistics of enrollment of each course
- Courses with entry degree of 0 are written into the queue
- Queue to get courses and write to the complete courses array
- Then reduce the enrollment of the course to 1. If the enrollment of the course to 1 is 0, join the queue
- Finally, judge whether the number of courses matches

`import java.util.LinkedList; import java.util.Queue; /** * @author ffzs * @describe * @date 2020/5/17 */ public class findOrder { public int[] findOrder (int numCourses, int[][] prerequisites) { if (numCourses == 0) return prerequisites[0]; // Create entry table int[] indegree = new int[numCourses], res = new int[numCourses]; for (int[] pr: prerequisites) { indegree[pr[0]]++; } Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < indegree.length; i++) { if (indegree[i] == 0) queue.offer(i); } int count = 0; while (!queue.isEmpty()) { int index = queue.poll(); res[count++] = index; for (int[] pr: prerequisites) { if (pr[1] == index) { if (indegree[pr[0]] == 1) queue.offer(pr[0]); else indegree[pr[0]] --; } } } return count == numCourses? res: new int[0]; } }`

## Advanced

- In fact, it is faster to use depth search
- We can build a list to store the course relationship, similar to the figure below
- If there is no correlation, it will be put into the curriculum directly
- If there is an association, use recursion to judge whether the associated course can be completed
- In order to determine whether there is a circular state, we build three states:
- Not searched: 0
- Searching: 1
- Completion: - 1

- If there is a link in the course description in the search again, you can't go back to normal learning

`class Solution { int[] step, res; int count = 0; ArrayList<Integer>[] adjacent; public int[] findOrder(int numCourses, int[][] prerequisites) { if (numCourses==0) return new int[0]; step = new int[numCourses]; res = new int[numCourses]; adjacent = new ArrayList[numCourses]; for (int i = 0; i < numCourses ; i++) adjacent[i] = new ArrayList<>(); for (int[] pr:prerequisites) adjacent[pr[0]].add(pr[1]); for (int i = 0; i < numCourses; i++) if (isCycle(i)) return new int[0]; return res; } public boolean isCycle (int i) { if (step[i]==1) return true; if (step[i]==-1) return false; step[i] = 1; for (int l: adjacent[i]) if (isCycle(l)) return true; res[count++] = i; step[i] = -1; return false; } }`