leetcode 207 课程表
透过现象看本质,其实就是找这些课程构成的图中是否存在环。自己写了一个朴素的拓扑排序,其中通过入度和出度判断。不断的循环,找到入度为0的节点,并且删除所有以该点为起点的边,之后再进行循环。若是找不到入度为0的起点并且节点数不为0,则代表存在环,反之则不存在。贴民工代码
1 class Solution { 2 public: 3 bool canFinish(int numCourses, vector<vector<int>>& prerequisites) 4 { 5 vector<vector<int>> pre(numCourses); 6 //入度 7 vector<int> in(numCourses,0); 8 //出度 9 vector<int> out(numCourses,0); 10 for(vector<int>& temp:prerequisites) 11 { 12 pre[temp[1]].push_back(temp[0]); 13 in[temp[0]]++; 14 out[temp[1]]++; 15 } 16 int newSize = numCourses; 17 queue<int> que; 18 while(1) 19 { 20 //找到入度为0的节点 21 for(int i = 0 ; i< numCourses ; i++) 22 { 23 if(in[i] == 0) 24 que.push(i); 25 } 26 //cout<<in[0]<<endl; 27 if(que.empty() && newSize>0) 28 return false; 29 else if(que.empty() && newSize == 0) 30 return true; 31 //将对应的边删除 32 while(!que.empty()) 33 { 34 int tempOut = que.front(); 35 //cout<<tempOut<<endl; 36 for(auto temp:pre[tempOut]) 37 { 38 //cout<<temp<<endl; 39 //cout<<in[temp]<<endl; 40 //对应的节点的入度-1 41 in[temp]--; 42 } 43 que.pop(); 44 newSize--; 45 //入度变为-1,代表删除 46 in[tempOut]--; 47 } 48 } 49 return false; 50 } 51 };
看了一下题解,上面这种算是广度优先搜索,而深度优先搜索的方法就需要用到递归。对于某一个节点有三种状态,未搜索,已搜索与搜索中。对于某一个未搜索节点,去搜索其所有的周围节点,周围节点探索完成之后就回溯到本结点,并将其入栈,视作已搜索。如果搜索过程中遇到一个搜索中的节点,说明从该节点出发能够回到该节点,说明拓扑中存在环。
1 class Solution { 2 public: 3 vector<vector<int>> edges; 4 vector<int> visited; 5 bool vaild = true; 6 void dfs(int u) 7 { 8 visited[u] = 1; 9 for(int v:edges[u]) 10 { 11 if(visited[v] == 0) 12 { 13 dfs(v); 14 if(!vaild) 15 return; 16 } 17 else if(visited[v] == 1) 18 { 19 vaild = false; 20 return; 21 } 22 } 23 visited[u] = 2; 24 } 25 bool canFinish(int numCourses, vector<vector<int>>& prerequisites) 26 { 27 edges.resize(numCourses); 28 visited.resize(numCourses); 29 for(const auto& info:prerequisites) 30 edges[info[1]].push_back(info[0]); 31 for(int i = 0 ; i < numCourses ; i++) 32 { 33 if(visited[i] == 0) 34 dfs(i); 35 } 36 return vaild; 37 } 38 };

浙公网安备 33010602011771号