题目链接
https://www.nowcoder.com/practice/71cde4dee669475f94d8d38832374ada
题目描述
给定一个 n 个节点的邻接矩阵 m。 节点定义为城市,如果 a 城市与 b 城市相连, b 与 c 城市相连,尽管 a 与 c 并不直接相连,但可以认为 a 与 c 相连,定义 a,b,c 是一个城市群。
矩阵 m[i][j] = 1
表示第 i 个城市和第 j 个城市直接相连,否则表示不相连。
请你找出共有多少个城市群。
数据范围:
1≤n≤200
, 矩阵中只包含0和1
示例1
输入:
[[1,1,0],[1,1,0],[0,0,1]]
复制
返回值:
2
复制
说明:
1 2 相连,3 独立,因此是 3 个城市群。
示例2
输入:
[[1,1,0,0],[1,1,1,0],[0,1,1,0],[0,0,0,1]]
复制
返回值:
2
复制
说明:
1 , 2相连 ;2 ,3相连,4独立,因此是 1,2,3 属于一个城市群,4属于一个城市群。
AC代码
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型vector<vector<>>
* @return int整型
*/
int citys(vector<vector<int> >& m) {
int numCities = m.size();
vector<int> clusters(numCities, -1); // 初始化每个城市所属的群组编号为-1
vector<bool> visited(numCities, false); // 记录已访问的城市
int clusterCount = 0;
// 遍历所有城市
for (int i = 0; i < numCities; ++i) {
if (!visited[i]) { // 如果城市未被访问过
clusterCount++; // 新增一个城市群
visited[i] = true;
clusters[i] = clusterCount;
// 使用队列进行广度优先搜索
queue<int> bfsQueue;
bfsQueue.push(i);
while (!bfsQueue.empty()) {
int currentCity = bfsQueue.front();
bfsQueue.pop();
// 遍历当前城市的所有邻居
for (int j = 0; j < numCities; ++j) {
if (m[currentCity][j] && clusters[j] == -1 && !visited[j]){
visited[j] = true;
clusters[j] = clusterCount;
bfsQueue.push(j);
}
}
}
}
}
return clusterCount;
}
};
代码解释
具体来说,函数首先初始化一个clusters数组,用于记录每个城市所属的城市群编号,初始值为-1,表示城市未被访问过。然后,函数遍历所有城市,对于未被访问过的城市,将其加入当前城市群,并使用队列进行广度优先搜索(BFS),遍历当前城市的所有邻居,将未被访问过的邻居城市加入当前城市群,并将其加入队列中。最后,函数返回城市群数量。
需要注意的是,函数使用了队列进行广度优先搜索,而不是栈进行深度优先搜索。这是因为广度优先搜索可以保证每个城市群中的城市都是连通的,而深度优先搜索可能会导致一些城市被遗漏。此外,函数在遍历邻居城市时,使用了clusters[j] == -1 && !visited[j]
来判断城市是否未被访问过,这样可以避免重复访问已经访问过的城市,从而提高效率。