该题主要运用了图的连通性 接着使用染色法解决该问题
染色法:标记所有节点为false 访问后 将其标记位true
class Solution {
int n; // 代表n个数据
bool colors[201]; // 标记是否访问到
void dfs(vector<vector<int>>& isConnected, int u) { // u代表从哪个点开始访问
if (colors[u]) { // 递归终止条件:该节点已经被访问
return;
}
colors[u] = true; // 标记位以访问
for (int i = 0; i < n; ++i) {
if (isConnected[u][i]) {
dfs(isConnected, i);
}
}
}
public:
int findCircleNum(vector<vector<int>>& isConnected) {
n = isConnected.size();
memset(colors, false, sizeof(isConnected)); // 初始化全部为未访问
int cnt = 0;
for (int i = 0; i < isConnected.size(); ++i) {
if (colors[i] == false) { //只访问未访问过的节点
dfs(isConnected, i);
++cnt;
}
}
return cnt;
}
};
在递归过程中 开始由于判断错了一个条件 导致不能通过全部案例
for (int i = 0; i < n; ++i) {
if (isConnected[u][i]) {
dfs(isConnected, i);
}
}
写成了
for (int i = u + 1; i < n; ++i) {
if (isConnected[u][i]) {
dfs(isConnected, i);
}
}
我想的是这个节点既然是连通的 那么必将是先访问数字小的节点 在访问数字大的节点 我这么写之后 错了 我以为是 数组越界的问题 但是这个i如果超出了数组的边界不会进去for循环内部 我又把 这一句改为 i = u 我觉得就是没有必要去继续访问比自己小的节点了 但是忽略了一个问题 就是小的节点可能直接和一个更大的节点相连 并没有和另一个小的相连 这样子的话 传入的起始节点就会很大 但是大的节点和另一个小的相连了 但是访问不到 导致得到结果偏大的问题
例如下面的这个案例
如果按照错误的执行 将是这样子的 执行顺序
得到的结果会是2 正确是1
正确的执行顺序