原题(Medium):
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

思路:递归
这题类型跟我们之前做过的一题单词搜索类似。所以我在看到这题之后,就想到了可以用与之相同的思路:建立一个代表搜索方向的数组,在当前坐标下,如果往某个方向移动一格是符合一定条件的,就往该方向移动一格,且是递归形式的移动。在这里条件就是不超越边界,且该方向上有岛屿可供移动,且是未被访问过的。如果4个方向都尝试完毕,就可以返回了。为了防止重复访问已经被访问过的岛屿格,需要一个访问数组做记录。在递归过程中,每前进一格(符合条件才会前进),就设置该格已被访问。
1 int xy[4][4] = { { 1,0 },{ 0,-1 },{ -1,0 },{ 0,1 } }; //代表搜索方向的数组
2
3 void helper(vector<vector<int>>& grid, int x, int y, vector<vector<bool>>& visited)
4 {
5 visited[y][x] = true;
6 for (int i = 0; i < 4; i++)
7 {
8 //以当前网格起点,尝试其四周能能否移动,能就继续递归移动,直至整座岛屿被访问完毕
9 int tempX = x + xy[i][0];
10 int tempY = y + xy[i][1];
11 //不超越边界,且该方向上有岛屿可供移动,且是未被访问过的
12 if (tempY >= 0 && tempY<grid.size() && tempX >= 0 && tempX<grid[0].size() && grid[tempY][tempX] && !visited[tempY][tempX])
13 helper(grid, tempX, tempY, visited);
14 }
15 }
16 int numIslands(vector<vector<int>>& grid) {
17 vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size(), false));
18
19 int count = 0;
20
21 for (int i = 0; i<grid.size(); i++)
22 for (int j = 0; j< grid[0].size(); j++)
23 {
24 if (grid[i][j] && !visited[i][j])
25 {
26 //主函数:从网格中查找每一个岛屿,只要发现一格陆地,整座岛屿都会在递归中被访问,那么在之后的查找中便不会再次访问
27 helper(grid, i, j, visited);
28 //每进来这里表示发现了一座岛屿,计数器+1
29 count++;
30 }
31 }
32 return count;
33 }
