Processing math: 100%

Leetcode 207 - Course Schedule

題目

Problem#

給你一個正整數 n 代表課程數量(從 0`` 到 n-1),並給你一個 prerequisites[i] = [a_i, b_i] (int[m][2])的陣列,代表如果要上課程b_i,一定要先上課程 a_i`
問你能不能上完所有課程?

測資限制#

  • 1n2000
  • 0m5000
  • (ai,bi) 不重複

想法#

觀察一下可以發現(第二個 example),如果課程存在循環依賴,則無法完成所以有課程,反之,不存在環則一定可以完成
=> 把 prerequisites 轉成 graph,接著用找環的演算法即可。

DFS 塗顏色,一開始全部都白色(0),接著開始 dfs,遇到白色的點就塗上紅色(1),如果在 dfs 的過程遇到紅色(1)的點,代表存在環。
為了要枚舉 n 個點當起點去 dfs ,所以如果點 i 的邊都 dfs 完了,則把點 i 塗成藍色(2),之後找沒有塗過的點(白色0)去 dfs

  • 時間複雜度: O(n+m)
  • 空間複雜度: O(n)

AC Code#

Copy
// dfs coloring
class Solution {
public:
bool canFinish(int n, vector<vector<int>>& preq)
{
int m = preq.size();
vector<char> color(n); // 0, 1, 2
vector<vector<int>> req(n, vector<int>{});
function<bool(int)> dfs = [&](int x) -> bool
{
color[x] = 1;
for(int y : req[x])
{
if(color[y] == 0)
{
color[y] = 1;
if(dfs(y))
return 1;
}
else if(color[y] == 1)
return 1;
}
color[x] = 2;
return 0;
};
for(int i = 0; i < m; i++)
{
int a = preq[i][0], b = preq[i][1];
req[a].push_back(b);
}
for(int i = 0; i < n; i++)
if(color[i] == 0 && dfs(i))
return 0;
return 1;
}
view raw leetcode/207.cpp delivered with ❤ by emgithub

賞析#

https://cp-algorithms.com/graph/finding-cycle.html