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 };

 

posted @ 2021-11-16 15:25  zhaohhhh  阅读(42)  评论(0)    收藏  举报