给定一个“1”(陆地)和“0”(水域)的二维网格地图,计算岛屿的数量。岛屿被水环绕,通过水平或垂直连接相邻的陆地而形成。你可以假设网格的四个边都被水包围着。
代码
解题思路:遍历图或者数组中的点,如果是岛屿的话,则修改它的值为其它值(非陆地和水),接着递归遍历它的上下左右,直到上下左右都是水或者到了边界则结束。
class Island {
public:
typedef struct tag_coordinate {
int x;
int y;
tag_coordinate(int i, int j) : x(i), y(j) {
}
}Coordinate;
int numIslands(vector<vector<char>>& grid) {
int number = 0;
for (unsigned i = 0; i < grid.size(); ++i) {
for (unsigned j = 0; j < grid[i].size(); ++j) {
if ('1' == grid[i][j]) {
++number;
numIslandsHelper(grid, i, j);
// recursive
//numIslandsHelperByRecursive(grid, i, j);
}
}
}
cleanup(grid);
return number;
}
void numIslandsHelper(vector<vector<char>>& grid, int i, int j) {
queue<Coordinate> q1;
q1.push(Coordinate(i, j));
while (!q1.empty()) {
int size = q1.size();
for (int i = 0; i < size; ++i) {
Coordinate c = q1.front();
q1.pop();
if (c.x >= 0 &&
c.x < grid.size() &&
c.y >= 0 &&
c.y < grid[0].size() &&
'1' == grid[c.x][c.y]) {
grid[c.x][c.y] = '#';
//up
q1.push(Coordinate(c.x, c.y - 1));
// down
q1.push(Coordinate(c.x, c.y + 1));
// left
q1.push(Coordinate(c.x - 1, c.y));
// right
q1.push(Coordinate(c.x + 1, c.y));
}
}
}
}
void numIslandsHelperByRecursive(vector<vector<char>>& grid, int i, int j) {
if (i >= 0 &&
i < grid.size() &&
j >= 0 &&
j < grid[0].size() &&
'1' == grid[i][j]) {
grid[i][j] = '#';
//up
numIslandsHelperByRecursive(grid, i, j -1);
// down
numIslandsHelperByRecursive(grid, i, j + 1);
// left
numIslandsHelperByRecursive(grid, i - 1, j);
// right
numIslandsHelperByRecursive(grid, i + 1, j);
}
}
void cleanup(vector<vector<char>>& grid) {
for (unsigned i = 0; i < grid.size(); ++i) {
for (unsigned j = 0; j < grid[0].size(); ++j) {
if ('#' == grid[i][j]) {
grid[i][j] = '1';
}
}
}
}
};
numIslands方法中,遍历所有的点,如果是岛屿的话,则岛屿数量加1,并且调用方法numIslandsHelper(迭代)或者方法numIslandsHelperByRecursive(递归)去遍历它的上下左右4个点,直到它的上下左右或者达到边界为止。为了防止重复遍历相应的点,每次在遍历完当前的点(陆地)后,把当前的点的值修改成#,表示当前这个点已经遍历过。
测试
11000
11000
00100
00011
根据上图的岛屿分布图来计算岛屿的数量:
int main()
{
vector<vector<char>> grid = {
{'1', '1', '0', '0', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '1', '0', '0'},
{'0', '0', '0', '1', '1'}
};
Island land;
int number = land.numIslands(grid);
cout << "grid:" << endl;
for (unsigned i = 0; i < grid.size(); ++i) {
for (unsigned j = 0; j < grid[0].size(); ++j) {
cout << grid[i][j];
}
cout << endl;
}
cout << "the number of islands is " << number << "." << endl;
return 0;
}
