仅供自己学习
思路:
这题只是在207.course schedule 上多加了一个数据结构来存储上课顺序的结构。
DFS:在将节点标为探索完成后,即visited[i]=2后加入进栈即可,因为是DFS所以遍历是从最后的课程加入,是需要前置课程才能学习的课程先入栈,所以最后应该reverse一下。这里我们用一个vector,便于反转操作。
代码:
1 class Solution { 2 public: 3 vector<vector<int>> edge; 4 vector<int> visited; 5 vector<int> res; 6 bool valid=true; 7 void dfs(int i){ 8 visited[i]=1; 9 for(auto& neighbor:edge[i]){ 10 if(visited[neighbor]==0){ 11 dfs(neighbor); 12 if(!valid) return; 13 } 14 else if(visited[neighbor]==1){ 15 valid=false; 16 return; 17 } 18 } 19 visited[i]=2; 20 res.push_back(i); 21 } 22 vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { 23 edge.resize(numCourses); 24 visited.resize(numCourses); 25 for(const auto& ex:prerequisites){ 26 edge[ex[1]].push_back(ex[0]); 27 } 28 for(int i=0;i<numCourses&&valid;++i){ 29 if(!visited[i]) 30 dfs(i); 31 } 32 if(!valid) return {}; 33 reverse(res.begin(),res.end()); 34 return res; 35 } 36 };
BFS同,因为BFS用了一个队列,同样我们用一个vector来存课程的结果,当从队列弹出第一个元素后,就把他加入进vector即可,最后判断 res的长度是否等于课程数,等于则能上完所有课程返回res即可
代码:
1 class Solution { 2 public: 3 vector<vector<int>> edge; 4 vector<int> res; 5 vector<int> indeg; 6 vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { 7 edge.resize(numCourses); 8 indeg.resize(numCourses); 9 for(const auto& ex:prerequisites){ 10 edge[ex[1]].push_back(ex[0]); 11 ++indeg[ex[0]]; 12 } 13 queue<int> q; 14 for(int i=0;i<numCourses;++i){ 15 if(indeg[i]==0) 16 q.push(i); 17 } 18 while(!q.empty()){ 19 int temp=q.front(); 20 q.pop(); 21 res.push_back(temp); 22 for(auto& neighbor:edge[temp]){ 23 --indeg[neighbor]; 24 if(indeg[neighbor]==0) 25 q.push(neighbor); 26 } 27 } 28 if(res.size()!=numCourses) 29 return {}; 30 return res; 31 } 32 };