目录
一,题目描述
英文描述
中文描述
示例与说明
二,解题思路
并查集
DFS
三,AC代码
C++
Java
四,解题过程
第一博
第二搏
一,题目描述
英文描述
There are n cities. Some of them are connected, while some are not. If city a is connected directly with city b, and city b is connected directly with city c, then city a is connected indirectly with city c.
A province is a group of directly or indirectly connected cities and no other cities outside of the group.
You are given an n x n matrix isConnected where isConnected[i][j] = 1 if the ith city and the jth city are directly connected, and isConnected[i][j] = 0 otherwise.
Return the total number of provinces.
中文描述
有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。
省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。
返回矩阵中 省份 的数量。
示例与说明
?
来源:力扣(LeetCode) 链接:力扣 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
?
二,解题思路
并查集
并查集的基本题型。
不熟悉的同学可以看看这里的并查集介绍@ &再见萤火虫& 【并查集【算法笔记/晴神笔记】】
DFS
城市的连接可以看作一棵多叉树,dfs可以遍历树上的任何一个节点,只需要将每个遍历过的节点标记为已遍历,已遍历过的节点不再重复遍历,就不会陷入循环。
这样有几棵树,就有几个省份。
三,AC代码
C++
class Solution {
public:
int findCircleNum(vector<vector<int>>& isConnected) {
vector<bool> visited(isConnected.size());
int ans;
for (int i = 0; i < isConnected.size(); i++) {
if (visited[i]) continue;
dfs(isConnected, visited, i);
ans++;
}
return ans;
}
void dfs (vector<vector<int>>& isConnected, vector<bool>& visited, int cur) {
visited[cur] = true;
for (int i = 0; i < isConnected[cur].size(); i++) {
if (isConnected[cur][i] && !visited[i]) {
dfs(isConnected, visited, i);
}
}
}
};
Java
class Solution {
int[] father;
int findFather (int n) {
if (father[n] != n) {
father[n] = findFather(father[n]);
}
return father[n];
}
void union (int a, int b) {
int A = findFather(a);
int B = findFather(b);
if (A != B) father[Math.max(A, B)] = Math.min(A, B);// !!!最好限定一下,比如偏向取较小的father作为新的father
}
public int findCircleNum(int[][] isConnected) {
father = new int[isConnected.length];
for (int i = 0; i < father.length; i++) father[i] = i;
for (int i = 0; i < isConnected.length; i++) {
for (int j = 0; j < i; j++) {
if (isConnected[i][j] == 1) {
union(i, j);
}
}
}
int ans = 0;
for (int i = 0; i < father.length; i++) {
if (father[i] == i) ans++;// !!!采用此方法计算联通集的个数,而不是采用set
}
return ans;
}
}
?
四,解题过程
第一博
时间长没做并查集的题目了,细节地方都给忘掉了。
不执行的话,部分集合没有统一父节点,也就是没有完全实现路径压缩。
而直接用father[i] == i就不会出现这种情况,因为算法的流程已经走完,并查集的树形结构已经形成,一棵树只有一个根节点,也就是只有一个节点三是father[i] == i。
第二搏
果然还是dfs熟悉一点,一发如魂
?
|