Course Schedule 解答

本文探讨了课程安排问题,即判断给定课程总数及先修课程关系下是否能完成所有课程。通过两种方法解决:一是使用深度优先搜索判断图中是否存在环;二是采用拓扑排序并维护一个入度为0的顶点队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Question

There are a total of n courses you have to take, labeled from 0 to n - 1.

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]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

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.

Solution 1 -- DFS

This question can be transferred to judge whether the graph has cycle.

There are two key points for this question.

1. How to construct adjacency list according to edge lists? (Graph representation)

Usually, we use ArrayList[] to represent adjacency list.

2. How to use DFS to judge whether the graph has cycle. This solution can be further modified to implement topological sort.

Time complexity O(|V| + |E|)

 1 public class Solution {
 2     public boolean canFinish(int numCourses, int[][] prerequisites) {
 3         if (prerequisites == null || prerequisites.length == 0)
 4             return true;
 5         // Construct adjacency list
 6         ArrayList<Integer>[] adjacencyList = new ArrayList[numCourses];
 7         for (int i = 0; i < numCourses; i++) {
 8             ArrayList<Integer> tmpList = new ArrayList<Integer>();
 9             tmpList.add(i);
10             adjacencyList[i] = tmpList;
11         }
12         for (int i = 0; i < prerequisites.length; i++) {
13             int[] currentPair = prerequisites[i];
14             adjacencyList[currentPair[0]].add(currentPair[1]);
15         }
16         
17         // DFS Because we need to judge whether the graph has cycle, we use three status for each node
18         // 0 -> not start; 1 -> start dfs, but not complete; 2 -> complete dfs; 
19         short[] used = new short[numCourses];
20         for (int i = 0; i < numCourses; i++) {
21             if (used[i] == 0) {
22                 boolean result = dfs(adjacencyList, used, i);
23                 if (!result)
24                     return false;
25             }
26         }
27         return true;
28     }
29     
30     private boolean dfs(ArrayList<Integer>[] graph, short[] used, int i) {
31         used[i] = 1;
32         ArrayList<Integer> neighbor = graph[i];
33         for (int j = 1; j < neighbor.size(); j++) {
34             int index = neighbor.get(j);
35             if (used[index] == 1)
36                 return false;
37             if (used[index] == 2)
38                 continue;
39             if (used[index] == 0) {
40                 if (!dfs(graph, used, index))
41                     return false;
42             }
43         }
44         used[i] = 2;
45         return true;
46     }
47     
48 }

 Solution 2

We adopt second way to implement topological sort.

We maintain a queue to store vertices whose in-degree is 0. Time complexity O(|V| + |E|).

 1 public class Solution {
 2     public boolean canFinish(int numCourses, int[][] prerequisites) {
 3         if (prerequisites == null || prerequisites.length == 0)
 4             return true;
 5         // Construct adjacency list
 6         ArrayList<Integer>[] adjacencyList = new ArrayList[numCourses];
 7         for (int i = 0; i < numCourses; i++) {
 8             ArrayList<Integer> tmpList = new ArrayList<Integer>();
 9             tmpList.add(i);
10             adjacencyList[i] = tmpList;
11         }
12         for (int i = 0; i < prerequisites.length; i++) {
13             int[] currentPair = prerequisites[i];
14             adjacencyList[currentPair[0]].add(currentPair[1]);
15         }
16         // Maintain a queue to store vertices with in-degree is 0
17         Queue<Integer> queue = new LinkedList<Integer>();
18         int[] inDegree = new int[numCourses];
19         Arrays.fill(inDegree, 0);
20         // Initialize in-degree array
21         for (ArrayList<Integer> tmpList : adjacencyList) {
22             int size = tmpList.size();
23             for (int i = 1; i < size; i++)
24                 inDegree[tmpList.get(i)]++;
25         }
26         // Initialize queue
27         for (int i = 0; i < numCourses; i++) {
28             if (inDegree[i] == 0)
29                 queue.add(i);
30         }
31         if (queue.size() == 0)
32             return false;
33         int count = 0;
34         while (queue.size() > 0) {
35             int key = queue.remove();
36             ArrayList<Integer> neighbor = adjacencyList[key];
37             for (int i = 1; i < neighbor.size(); i++) {
38                 int tmp = neighbor.get(i);
39                 inDegree[tmp]--;
40                 if (inDegree[tmp] == 0) {
41                     queue.add(tmp);
42                 }
43             }
44             count++;
45         }
46         return count == numCourses;
47     }
48 }

 

转载于:https://www.cnblogs.com/ireneyanglan/p/4845384.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值