DFS O(n2 ) n次标记,每次标记需要扫描n个city,递归深度最多为n 用这个版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : int findCircleNum (vector <vector <int >>& M) { n = M.size(); visited.resize(n); int res = 0 ; for (int i = 0 ; i < n; ++i) { if (!visited[i]) { visit(M, i); ++res; } } return res; } void visit (const vector <vector <int >> &M, int u) { visited[u] = true ; for (int v = 0 ; v < n; ++v) { if (!visited[v] && M[u][v]) { visit(M, v); } } } int n; vector <bool > visited; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : int findCircleNum (vector <vector <int >>& M) { int n = M.size(); vector <bool > visited (n) ; int count = 0 ; for (int i = 0 ; i < n; ++i) { if (!visited[i]) { visited[i] = true ; dfs(M, i, visited); ++count; } } return count; } void dfs (const vector <vector <int >> &M, int i, vector <bool > &visited) { for (int j = 0 ; j < M.size(); ++j) { if (M[i][j] && !visited[j]) { visited[j] = true ; dfs(M, j, visited); } } } };
union-find amortized O(n2 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution {public : int findCircleNum (vector <vector <int >>& M) { int n = M.size(); UF uf (n) ; for (int i = 0 ; i < n - 1 ; ++i) { for (int j = i + 1 ; j < n; ++j) { if (M[i][j]) { uf.merge(i, j); } } } return uf.count; } struct UF { UF(int n) : count(n) { parent.resize(n); iota(parent.begin(), parent.end(), 0 ); } int getParent (int x) { while (parent[parent[x]] != parent[x]) { x = parent[x] = parent[parent[x]]; } return parent[x]; } void merge (int x, int y) { int px = getParent(x); int py = getParent(y); if (px != py) { parent[px] = py; --count; } } vector <int > parent; int count; }; };