207. Course Schedule(课程安排)
1 问题描述
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?
已知有n个课程,标记从0至n-1,课程之间是有依赖关系的,例如希望完成0课程,可能需要先完成1课程。已知n个课程的依赖关系,求是否可以将n个课程全部完成。
Example 1:
Input: 2, [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 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.
Note:
- The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
- You may assume that there are no duplicate edges in the input prerequisites.
2 思路
- 使用深度优先遍历:对输入进行分析,原始问题可以转换为有向图问题,当有向图无环时返回True,当有向图有环时返回False
- 使用宽度优先遍历:只将入度为0的点添加至队列。当完成一个顶点的搜索(从队 列取出),它指向的所有顶点入度都减1,若此时某顶点入度为0则添加至队列,若完 成宽度搜索后,所有的点入度都为0,则图无环,否则有环。
3 C++实现
- 图的实现
struct GraphNode{
int label;
std::vector<GraphNode *> neighbors;
GraphNode(int x) : label(x) {};
};
- 方法一:深度优先遍历
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<GraphNode *> graph;
vector<int> visit;
//创建图
for(int i=0; i<numCourses; i++) {
graph.push_back(new GraphNode(i));
visit.push_back(-1);
}
//连接图
for(int i=0; i<prerequisites.size(); i++) {
GraphNode* begin = graph[prerequisites[i].second];
GraphNode* end = graph[prerequisites[i].first];
begin->neighbors.push_back(end);
}
//遍历
for(int i=0; i<graph.size(); i++) {
if(visit[i] == -1 && !DFS_graph(graph[i], visit))
return false;
}
//回收内存
for(int i=0; i<graph.size(); i++) {
delete graph[i];
}
return true;
}
private:
bool DFS_graph(GraphNode *node, vector<int> &visit) {
//节点访问控制,-1表示没有访问,0表示正在访问,1表示访问完成
visit[node->label] = 0;
for(int i=0; i<node->neighbors.size(); i++) {
if(visit[node->neighbors[i]->label] == -1) {
if(DFS_graph(node->neighbors[i], visit) == 0)
return false;
}
else if(visit[node->neighbors[i]->label] == 0)
return false;
}
visit[node->label] = 1;
return true;
}
};
- 方法二,宽度优先(拓扑结构)
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<GraphNode *> graph;
vector<int> degree;
//创建图
for(int i=0; i<numCourses; i++) {
graph.push_back(new GraphNode(i));
degree.push_back(0);
}
//连接图
for(int i=0; i<prerequisites.size(); i++) {
GraphNode* begin = graph[prerequisites[i].second];
GraphNode* end = graph[prerequisites[i].first];
begin->neighbors.push_back(end);
degree[prerequisites[i].first]++;
}
queue<GraphNode *> Q;
for(int i=0; i<degree.size(); i++) {
if(degree[i] == 0)
Q.push(graph[i]);
}
while(!Q.empty()) {
GraphNode* node = Q.front();
Q.pop();
for(int i=0; i<node->neighbors.size(); i++) {
degree[node->neighbors[i]->label]--;
if(degree[node->neighbors[i]->label] == 0)
Q.push(node->neighbors[i]);
}
}
//回收内存
for(int i=0; i<graph.size(); i++) {
delete graph[i];
}
//回收内存
for(int i=0; i<degree.size(); i++) {
if (degree[i]){
return false;
}
}
return true;
}
};
继续阅读
- 我的微信小程序
- 这是我的微信小程序扫一扫
-
- 我的微信公众号
- 我的微信公众号扫一扫
-
评论