您的位置:首页 > 其它

LintCode_安排课程

2017-08-21 21:14 260 查看
你需要去上n门九章的课才能获得offer,这些课被标号为 
0
 到 
n-1
 。

有一些课程需要“前置课程”,比如如果你要上课程0,你需要先学课程1,我们用一个匹配来表示他们: 
[0,1]

给你课程的总数量和一些前置课程的需求,返回你为了学完所有课程所安排的学习顺序。
可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

样例

给定 n = 
2
, prerequisites
[[1,0]]


返回 
[0,1]

给定 n = 4, prerequisites = 
[1,0],[2,0],[3,1],[3,2]]


返回 
[0,1,2,3]
 or 
[0,2,1,3] 


思路:也就个拓扑排序,不过注意的是,题中并没有注明给出的图一定是有向无环图(DAG),所以在DFS递归的时候要顺便测试是否存在环,测试的方法也很简单。首先图中的每个节点有三个状态:一是未发现,二是已发现但未访问(仍可以继续递归下去), 三是已访问。若发现u所指向的v已经被发现,则说明存在一个环,及时退出递归返回一个空的结果。
另外也要注意数组的下标太大的话要把它声明成全局变量,或者使用 malloc函数分配内存。
vector<int> neighbors[100002]; //邻居集合
int status[100002]; //是否被访问过,0-未访问,1-被发现,2-已访问
//数组下标太大了得声明成一个全局变量
class Solution {
public:
/**
* @param numCourses a total of n courses
* @param prerequisites a list of prerequisite pairs
* @return the course order
*/
vector<int> result;
bool dfs(int r)
{
status[r]=1;
for(int i=0;i<neighbors[r].size();i++)
{
if(status[neighbors[r][i]]==0)
{
if(dfs(neighbors[r][i])==false) //回退
return false;
}
else if(status[neighbors[r][i]]==1) //如果发现一个邻居已经被发现了,则说明图中存在环,不是DAG
return false; //所以要及时回退
}
result.push_back(r);
status[r]=2; //这个一定要记得写
return true;
}
vector<int> findOrder(int numCourses, vector<pair<int, int> >& prerequisites) {
// Write your code here
for(int i=0;i<numCourses;i++) status[i]=0;
for(int i=0;i<prerequisites.size();i++)
{
neighbors[prerequisites[i].second].push_back(prerequisites[i].first);
}
for(int i=0;i<numCourses;i++)
{
if(status[i]==0)
if(dfs(i)==false) //若存在一个环,应返回一个空的vector
{
result.clear();
return result;
}
}
reverse(result.begin(),result.end());
return result;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: