No207. Course Schedule
来源:互联网 发布:淘宝助理快速发布宝贝 编辑:程序博客网 时间:2024/06/11 09:15
一、题目描述
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?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
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.
二、我的解法
1、解题思路
一个图中的边可以分为树边、前向边、回边和横边,我们重点关注前向边、回边和横边的性质。如果采用DFS对图进行搜一遍,并且按照访问和返回的顺序,对图中的每个节点进行标号,左边的数字(pre)表示访问的序号,右边的数字(post)表示返回的序号,则一幅图可以表示为以下状态:
其中假定一条边是右v指向u:v—>u,则有如下性质:
回边:pre(v)>pre(u) , post(v)<post(u)
前向边:pre(v)<pre(u) , post(v)>post(u)
横边:pre(v)>pre(u) , post(v)>post(u)
所以根据给出的信息,构建图,然后根据图的结构构建DFS访问后每个节点的pre和post值,最后根据pre和post值检查图中是否含有回边,如果包含回边,则图中有环。
用vector<unordered_set<int>>存储图的信息,用vector<pair<int,int>>存储pre和post值,全局变量count表示访问和返回的顺序,函数dfs表示深度优先遍历图,并对遍历的每个节点标记pre和post。
2、代码实现
class Solution {public: int count =0; bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { vector<unordered_set<int>> graph(numCourses); for(auto p:prerequisites){ graph[p.second].insert(p.first); } vector<pair<int,int>> point(numCourses,make_pair(0,0)); for(int i=0;i<numCourses;i++){ dfs(graph,point,i); } for(int v=0;v<numCourses;v++) for(int u:graph[v]) if(point[v].first>point[u].first&&point[v].second<point[u].second) return false; return true; } void dfs(vector<unordered_set<int>>& graph,vector<pair<int,int>>& point,int node){ if(point[node].first==0){ point[node].first=++count; for(auto neigh:graph[node]) dfs(graph,point,neigh); point[node].second=++count; } }};三、其它解法一
1、解题思路
DFS遍历图,如果在一条搜索路径中,访问了该路径中已经访问过的节点,则说明有环。该方法需要注意的是,要创建两个vector:visited和onpath,其中visited用于记录各条路径中已经访问过的节点,目的是为了避免重复访问节点,已经访问过的就不用在访问了,而onpath是用于记录一条路径中访问过的节点,用于检查是否有环,所以在路径访问结束之后,onpath中的值要清空,代码中visited和onpath都是用true表示访问过,false表示未访问。
2、代码实现
class Solution {public: bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { vector<unordered_set<int>> graph(numCourses); for(auto p:prerequisites) graph[p.second].insert(p.first); vector<bool> visited(numCourses,false); vector<bool> onpath(numCourses,false); for(int i=0;i<numCourses;i++) if(!visited[i]&&dfs_circle(graph,i,visited,onpath)) return false; return true; } bool dfs_circle(vector<unordered_set<int>>& graph,int node,vector<bool>& visited,vector<bool>& onpath){ if(visited[node])return false; onpath[node]=visited[node]=true; for(auto neigh:graph[node]) if(onpath[neigh]||dfs_circle(graph,neigh,visited,onpath)) return true; onpath[node] = false; return false; }};
四、其它解法二
1、解题思路
BFS遍历图,并通过compute_indegree函数记录每个节点的入度。然后遍历图,如果没有一个节点的入度为0,则有环,如果有至少一个节点的入度为0,则暂时无环,将入度为0的节点标记下来,其它所有与该入度为0的节点相连的节点的入度减一,直至把所有节点都遍历完。
2、代码实现
class Solution {public: bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { vector<unordered_set<int>> graph(numCourses); for (auto pre : prerequisites) graph[pre.second].insert(pre.first); vector<int> degrees = compute_indegree(graph); for (int i = 0; i < numCourses; i++) { int j = 0; for (; j < numCourses; j++) if (!degrees[j]) break; if (j == numCourses) return false; degrees[j] = -1; for (int neigh : graph[j]) degrees[neigh]--; } return true; } vector<int> compute_indegree(vector<unordered_set<int>>& graph) { vector<int> degrees(graph.size(), 0); for (auto neighbors : graph) for (int neigh : neighbors) degrees[neigh]++; return degrees; }};
- No207. Course Schedule
- 【Course Schedule】Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Course Schedule
- Logback:layout官方手册
- python 利用库sklearn 中的 grid_search对svm 参数寻优(借鉴)
- hadoop 集群搭建 干货
- 为何这电脑跑得比谁都快?Win10必做的9项优化
- 使用的bean工厂ApplicationContext
- No207. Course Schedule
- Adventure of Super Mario UVA
- HDFS权限控制
- 【js实例】js中的5种基本数据类型和9种操作符
- tcp/ip编程之多客户端的实现
- CT及MR的定位线功能实现
- 微网页开发弹出“非微信官方网页 转换为手机预览模式”的原因
- 两个easyui combobox 逻辑关联
- android动态适配