Title Description
You must take numCourses this semester, marked 0 to numCourses - 1. Some prerequisite courses are required before taking some courses. The prerequisite courses are given by the array prerequisites, where prerequisites[i] = [ai, bi], which means that if you want to learn course ai, you must learn course bi first.
For example, the prerequisite course pair [0, 1] indicates that if you want to learn course 0, you need to complete course 1 first. Please judge whether it is possible to complete all courses? If yes, return true; Otherwise, false is returned.
Example 1:
Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: there are 2 courses in total. You need to complete course 0 before studying course 1. This is possible.
Example 2:
Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: there are 2 courses in total. Before learning course 1, you need to complete course 0; You should also complete course 1 before studying course 0. It's impossible.
Solution:
According to the meaning of the question, a prerequisite course is required before learning a course, that is, there is an edge from the prerequisite course to the course. Topological sorting can be used to solve the problem. Nodes represent courses, and a directed edge indicates that a prerequisite course points to the course to be studied.
Topological sorting: directed acyclic graph (at least one point with 0 degree)
Process: first, count the penetration of all points. Join the point with penetration of 0. Take a point from the head of the team. After taking the point, the penetration of the connected point is reduced by one. If it is reduced to 0, join the point. Until the end of the loop, it is necessary to judge whether the number of nodes traversed is equal to the given number. If they are equal, it indicates that there is a topological order.
class Solution { public: bool canFinish(int n, vector<vector<int>>& edges) { vector<vector<int>> g(n); vector<int> d(n); for(auto &x:edges) { int b=x[0],a=x[1]; g[a].push_back(b);//Indicates the side where a points to b d[b]++;//The penetration of b is increased by one } queue<int> q; for(int i=0;i<n;i++) { if(d[i]==0) q.push(i); } int cnt=0;//Number of points traversed while(!q.empty()) { auto t=q.front(); q.pop(); cnt++; for(auto i:g[t]) { d[i]--; if(d[i]==0) q.push(i); } } return cnt==n; } };
Course Schedule II
Now you have a total of N courses to choose, recorded as 0 to n-1. Some prerequisite courses are required before taking some courses. For example, to learn course 0, you need to complete course 1 first. We use a match to represent them: [0,1]
Given the total number of courses and their prerequisites, return to the learning order you arranged to complete all courses. There may be multiple correct orders. You just need to return one. If it is impossible 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 course 1, you need to complete course 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 study course 3, you should complete course 1 and course 2 first. And both course 1 and course 2 should be ranked after course 0.
Therefore, a correct course order is [0,1,2,3]. Another correct order is [0,2,1,3].
explain:
The prerequisite for entering is the graph represented by the edge list, not the 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 directed graph. If there is a loop, there is no topological sorting, so it is impossible to select all courses for learning.
Topology sorting through DFS - a wonderful video tutorial on Coursera (21 minutes), which introduces the basic concept of topology sorting.
Topology sorting can also be completed through BFS.
Problem solution
The topological order is stored in the queue. You only need to print it out. It should be noted that if there is no topological order, you need to output null.
class Solution { public: vector<int> findOrder(int n, vector<vector<int>>& edges) { vector<vector<int>> g(n); vector<int> d(n); vector<int> res; for(auto &x:edges) { int b=x[0],a=x[1]; g[a].push_back(b);//Indicates the side where a points to b d[b]++;//The penetration of b is increased by one } queue<int> q; for(int i=0;i<n;i++) { if(d[i]==0) q.push(i); } int cnt=0;//Number of points traversed while(!q.empty()) { auto t=q.front(); res.push_back(t); q.pop(); cnt++; for(auto i:g[t]) { d[i]--; if(d[i]==0) q.push(i); } } if (res.size() < n) res = {};//If there is no complete topological order, the output is null return res; } };