classSolution { public: voiddfs(vector<vector<int>>& isConnected, vector<int>& visited, int cities, int i){ for (int j = 0; j < cities; j++) { if (isConnected[i][j] == 1 && !visited[j]) { visited[j] = 1; dfs(isConnected, visited, cities, j); } } }
intfindCircleNum(vector<vector<int>>& isConnected){ int cities = isConnected.size(); vector<int> visited(cities); int provinces = 0; for (int i = 0; i < cities; i++) { if (!visited[i]) { dfs(isConnected, visited, cities, i); provinces++; } } return provinces; } };
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funcfindCircleNum(isConnected [][]int) (ans int) { vis := make([]bool, len(isConnected)) var dfs func(int) dfs = func(from int) { vis[from] = true for to, conn := range isConnected[from] { if conn == 1 && !vis[to] { dfs(to) } } } for i, v := range vis { if !v { ans++ dfs(i) } } return }
voiddfs(int** isConnected, int* visited, int cities, int i) { for (int j = 0; j < cities; j++) { if (isConnected[i][j] == 1 && !visited[j]) { visited[j] = 1; dfs(isConnected, visited, cities, j); } } }
intfindCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) { int cities = isConnectedSize; int visited[cities]; memset(visited, 0, sizeof(visited)); int provinces = 0; for (int i = 0; i < cities; i++) { if (!visited[i]) { dfs(isConnected, visited, cities, i); provinces++; } } return provinces; }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: deffindCircleNum(self, isConnected: List[List[int]]) -> int: defdfs(i: int): for j inrange(cities): if isConnected[i][j] == 1and j notin visited: visited.add(j) dfs(j) cities = len(isConnected) visited = set() provinces = 0
for i inrange(cities): if i notin visited: dfs(i) provinces += 1 return provinces
复杂度分析
时间复杂度:O(n^2),其中 n 是城市的数量。需要遍历矩阵 n 中的每个元素。
空间复杂度:O(n),其中 n 是城市的数量。需要使用数组 visited 记录每个城市是否被访问过,数组长度是 n,递归调用栈的深度不会超过 n。
intfindCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) { int cities = isConnectedSize; int visited[cities]; memset(visited, 0, sizeof(visited)); int provinces = 0; int que[cities * cities]; int left = 0, right = 0; for (int i = 0; i < cities; i++) { if (!visited[i]) { que[right++] = i; while (left < right) { int j = que[left++]; visited[j] = true; for (int k = 0; k < cities; k++) { if (isConnected[j][k] == 1 && !visited[k]) { que[right++] = k; } } } provinces++; } } return provinces; }
[sol2-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: deffindCircleNum(self, isConnected: List[List[int]]) -> int: cities = len(isConnected) visited = set() provinces = 0 for i inrange(cities): if i notin visited: Q = collections.deque([i]) while Q: j = Q.popleft() visited.add(j) for k inrange(cities): if isConnected[j][k] == 1and k notin visited: Q.append(k) provinces += 1 return provinces
复杂度分析
时间复杂度:O(n^2),其中 n 是城市的数量。需要遍历矩阵 isConnected 中的每个元素。
空间复杂度:O(n),其中 n 是城市的数量。需要使用数组 visited 记录每个城市是否被访问过,数组长度是 n,广度优先搜索使用的队列的元素个数不会超过 n。
for (let i = 0; i < cities; i++) { for (let j = i + 1; j < cities; j++) { if (isConnected[i][j] == 1) { union(parent, i, j); } } } let provinces = 0; parent.forEach((element, index) => { if (element === index) { provinces++; } });
classSolution { public: intFind(vector<int>& parent, int index){ if (parent[index] != index) { parent[index] = Find(parent, parent[index]); } return parent[index]; }
voidUnion(vector<int>& parent, int index1, int index2){ parent[Find(parent, index1)] = Find(parent, index2); }
intfindCircleNum(vector<vector<int>>& isConnected){ int cities = isConnected.size(); vector<int> parent(cities); for (int i = 0; i < cities; i++) { parent[i] = i; } for (int i = 0; i < cities; i++) { for (int j = i + 1; j < cities; j++) { if (isConnected[i][j] == 1) { Union(parent, i, j); } } } int provinces = 0; for (int i = 0; i < cities; i++) { if (parent[i] == i) { provinces++; } } return provinces; } };
funcfindCircleNum(isConnected [][]int) (ans int) { n := len(isConnected) parent := make([]int, n) for i := range parent { parent[i] = i } var find func(int)int find = func(x int)int { if parent[x] != x { parent[x] = find(parent[x]) } return parent[x] } union := func(from, to int) { parent[find(from)] = find(to) }
for i, row := range isConnected { for j := i + 1; j < n; j++ { if row[j] == 1 { union(i, j) } } } for i, p := range parent { if i == p { ans++ } } return }
intFind(int* parent, int index) { if (parent[index] != index) { parent[index] = Find(parent, parent[index]); } return parent[index]; }
voidUnion(int* parent, int index1, int index2) { parent[Find(parent, index1)] = Find(parent, index2); }
intfindCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) { int cities = isConnectedSize; int parent[cities]; for (int i = 0; i < cities; i++) { parent[i] = i; } for (int i = 0; i < cities; i++) { for (int j = i + 1; j < cities; j++) { if (isConnected[i][j] == 1) { Union(parent, i, j); } } } int provinces = 0; for (int i = 0; i < cities; i++) { if (parent[i] == i) { provinces++; } } return provinces; }