📅  最后修改于: 2023-12-03 14:55:33.849000             🧑  作者: Mango
岛屿数量是一道非常经典的算法问题,给定一个由 0 和 1 组成的矩阵 grid,其中 0 表示水,1 表示陆地。岛屿被水包围,被水包围的陆地是不同的岛屿。我们要求出矩阵中岛屿的数量。本文将介绍如何使用 DFS 算法来解决这个问题。
我们可以将矩阵看作一个无向图,每个元素对应一个节点,相邻且值为 1 的节点之间存在一条边。对于每一个值为 1 的节点,我们可以使用 DFS 算法来遍历所有相邻的节点,把所有值为 1 的节点标记为已访问,并且将它们的相邻节点加入到待访问节点列表中。当所有相邻节点都已经被访问完后,我们就找到了一个岛屿。
为了防止访问重复的节点,我们需要使用一个 visited 数组来记录每个节点是否已经被访问过。我们遍历所有节点,对于值为 1 的节点,如果它没有被访问过,就从这个节点开始进行 DFS 遍历,每次发现一个新的节点,就更新 visited 数组,并将该节点的相邻节点加入到待访问节点列表中。当一个岛屿被遍历完成后,我们增加岛屿数量的计数器,并继续遍历下一个未被访问的节点,直到矩阵中的所有节点都被遍历完。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void dfs(int** grid, int gridSize, int* gridColSize, int i, int j, bool** visited) {
if (i < 0 || i >= gridSize || j < 0 || j >= gridColSize[i] || visited[i][j] || grid[i][j] == 0) {
return;
}
visited[i][j] = true;
dfs(grid, gridSize, gridColSize, i - 1, j, visited);
dfs(grid, gridSize, gridColSize, i + 1, j, visited);
dfs(grid, gridSize, gridColSize, i, j - 1, visited);
dfs(grid, gridSize, gridColSize, i, j + 1, visited);
}
int numIslands(int** grid, int gridSize, int* gridColSize){
bool** visited = (bool**)calloc(gridSize, sizeof(bool*));
for (int i = 0; i < gridSize; i++) {
visited[i] = (bool*)calloc(gridColSize[i], sizeof(bool));
}
int count = 0;
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridColSize[i]; j++) {
if (grid[i][j] == 1 && !visited[i][j]) {
count++;
dfs(grid, gridSize, gridColSize, i, j, visited);
}
}
}
for (int i = 0; i < gridSize; i++) {
free(visited[i]);
}
free(visited);
return count;
}
本程序使用了递归和动态内存分配,需要注意内存泄漏的问题,特别是在 visited 数组的分配和释放过程中。在已访问的节点(visited[i][j])和岛屿数量计数器(count)之间没有直接的关系,因此在 DFS 函数中并没有尝试进行计数器的增加,而是在每次发现新岛屿时才增加计数器的值。