LeetCode | 200. 岛屿数量

原题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 }

posted @ 2019-10-29 08:51  羽园原华  阅读(172)  评论(0编辑  收藏  举报