描述
你这个学期必须选修 numCourses 门课程,记为0到numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组prerequisites 给出,其中prerequisites[i] = [ai, bi]
,表示如果要学习课程ai 则 必须 先学习课程 bi 。 例如,先修课程对[0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
示例 1:
输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
示例 2:
输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
提示:
1 <= numCourses <= 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有课程对 互不相同
解决方案
方法一:深度搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| class Solution { private ArrayList<ArrayList<Integer>> edges; private int[] visited; private boolean canFinish;
public boolean canFinish(int numCourses, int[][] prerequisites) { edges = new ArrayList<>(numCourses); for (int i = 0; i < numCourses; i++) { edges.add(new ArrayList<>()); } for (int[] pre : prerequisites) { edges.get(pre[0]).add(pre[1]); } visited = new int[numCourses]; canFinish = true; for (int i = 0; i < edges.size() && canFinish; i++) { if (visited[i] == 0) { dfs(i); } } return canFinish; }
private void dfs(int i) { if (!canFinish) { return; } visited[i] = 1; for (Integer next : edges.get(i)) { if (visited[next] == 0) { dfs(next); } else if (visited[next] == 1) { canFinish = false; return; } } visited[i] = 2; } }
|
方法二:广度搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Solution { List<List<Integer>> edges; int[] indeg;
public boolean canFinish(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]; for (int[] info : prerequisites) { edges.get(info[1]).add(info[0]); ++indeg[info[0]]; }
Queue<Integer> queue = new LinkedList<Integer>(); for (int i = 0; i < numCourses; ++i) { if (indeg[i] == 0) { queue.offer(i); } }
int visited = 0; while (!queue.isEmpty()) { ++visited; int u = queue.poll(); for (int v : edges.get(u)) { --indeg[v]; if (indeg[v] == 0) { queue.offer(v); } } }
return visited == numCourses; } }
|