310题目类似,但是数据结构可以选的更简单
------------恢复内容开始------------
题目
先修课程和后修课,比如高数离散修完,才能修数据结构
给定numcourse门课程,int[][]的先后计划。int[i][0]为要修的当前课程,int[i][1]为学这门课之前要修的课
207/210都在问:按照int[][],所有课程能否全部修完?(可能出现3,4 4,3这样的矛盾情况)
207:返回true/false即可
210:如能,返回按int[][]的修课顺序,如不能,返回空
There are a total of numCourses
courses you have to take, labeled from 0
to numCourses - 1
. You are given an array prerequisites
where prerequisites[i] = [ai, bi]
indicates that you must take course bi
first if you want to take course ai
.
- For example, the pair
[0, 1]
, indicates that to take course0
you have to first take course1
.
Return the ordering of courses you should take to finish all courses. If there are many valid answers, return any of them. If it is impossible to finish all courses, return an empty array.
Example 1:
Input: numCourses = 2, prerequisites = [[1,0]] Output: [0,1] Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1].
Example 2:
Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] Output: [0,2,1,3] Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3].
Example 3:
Input: numCourses = 1, prerequisites = [] Output: [0]
Constraints:
1 <= numCourses <= 2000
0 <= prerequisites.length <= numCourses * (numCourses - 1)
prerequisites[i].length == 2
0 <= ai, bi < numCourses
ai != bi
- All the pairs
[ai, bi]
are distinct.
思路
俩个辅助数据组(互为表里的感觉)
list<这门课,list<是哪些课的先修课>> data
level[i, 0~num]:学他之前,有多少先修课(由data生成)
如果level=0,则可以直接学。
先取出level=0的课程,再从data中找这些课程是哪些课的先修课,将这些课程对应的level减去1
-1后,level如果为0,则再次取出
取出的过程用queue,q.isEmpty循环条件,q.add加入level为0的, q.remove取出,并遍历这些课是哪些课的先修课~~
这是典型的广度优先搜索BFS模板 拓扑排序
代码
leetcode207
* 注意理解prerequisites[i][1]是pre先修课,prerequisites[i][0]是要修的课
* 不能直接List first=new ArrayList(prerequisites[i][0]);
* 注意是canTake.get(i)
public boolean canFinish(int numCourses, int[][] prerequisites) { Map<Integer,List<Integer>> data=new HashMap(); int[] level=new int[numCourses]; for(int i=0;i<prerequisites.length;i++){ if (data.containsKey(prerequisites[i][1])){ data.get(prerequisites[i][1]).add(prerequisites[i][0]);} else{ List first=new ArrayList<>(); first.add(prerequisites[i][0]); data.put(prerequisites[i][1],first); } level[prerequisites[i][0]]++; } Queue<Integer> q=new LinkedList(); for(int i=0;i<numCourses;i++){ if(level[i]==0){ q.add(i); } } while (!q.isEmpty()){ int takeID=q.remove(); List<Integer> canTake=data.get(takeID); for(int i=0;canTake!=null&&i<canTake.size();i++){ level[canTake.get(i)]--; if(level[canTake.get(i)]==0) q.add(canTake.get(i)); } } for(int i=0;i<numCourses;i++){ if(level[i]!=0) return false; } return true; }
leetcode210(加粗部分区别)
public int[] findOrder(int numCourses, int[][] prerequisites) { int[] ans=new int[numCourses]; int ansid=0; Map<Integer, List<Integer>> data=new HashMap(); int[] level=new int[numCourses]; for(int i=0;i<prerequisites.length;i++){ if (data.containsKey(prerequisites[i][1])){ data.get(prerequisites[i][1]).add(prerequisites[i][0]);} else{ List first=new ArrayList<>(); first.add(prerequisites[i][0]); data.put(prerequisites[i][1],first); } level[prerequisites[i][0]]++; } Queue<Integer> q=new LinkedList(); for(int i=0;i<numCourses;i++){ if(level[i]==0){ q.add(i); } } while (!q.isEmpty()){ int takeID=q.remove(); ans[ansid]=takeID; ansid++; List<Integer> canTake=data.get(takeID); for(int i=0;canTake!=null&&i<canTake.size();i++){ level[canTake.get(i)]--; if(level[canTake.get(i)]==0) q.add(canTake.get(i)); } } if (ansid!=numCourses) return new int[0]; return ans; }
ref. 非常感谢一姐
------------恢复内容结束------------