题目:
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。
示例:
输入:
11110
11010
11000
00000
输出: 1
来源:力扣(LeetCode)
方法一:深度搜索
该题可以看成一个寻找近邻值的问题,而在一个Grid上,这里定义的近邻就是上下左右,那么我们就可以下遍历二叉树一样进行深度遍历,假设其相当于”四叉树“。但是这样在遍历过程会出现重复的情况,所以我们在深度搜索的过程中把遇到的‘1’都置为‘0’,这样就可以避免重复。
1 # 深度搜索 2 class Solution(object): 3 def numIslands(self, grid): 4 nums = 0 5 for i in range(len(grid)): 6 for j in range(len(grid[0])): 7 if grid[i][j] == '1': 8 self.search_depth(grid, i, j) 9 nums += 1 10 return nums 11 12 def search_depth(self, grid, x, y): 13 if x >= len(grid) or y >= len(grid[0]) or x < 0 or y < 0: 14 return 15 16 if grid[x][y] == '1': 17 grid[x][y] = '0' 18 self.search_depth(grid, x-1, y) 19 self.search_depth(grid, x, y-1) 20 self.search_depth(grid, x+1, y) 21 self.search_depth(grid, x, y+1)
方法二:广度搜索
通过深度搜索可以很好的解决,但是递归过程会占用大量的内存,所以我们可以通过一个列表来代替递归过程。当我们遍历到一个点的时候,他是‘1’,成为岛屿点,所以我们把他的近邻的岛屿点,即上下左右的为‘1’的点都加入一个列表,然后不断的从列表中取出岛屿点,作为岛屿中心点,再次往列表里添加临近岛屿,直到列表为空时,计算完毕。这样就通过一个列表来代替了整个递归过程。
1 # 广度搜索 2 class Solution(object): 3 def numIslands(self, grid): 4 nr = len(grid) 5 if nr == 0: 6 return 0 7 nc = len(grid[0]) 8 num_islands = 0 9 for r in range(nr): 10 for c in range(nc): 11 if grid[r][c] == "1": 12 num_islands += 1 13 grid[r][c] = "0" 14 neighbors = collections.deque([(r, c)]) 15 while neighbors: 16 row, col = neighbors.popleft() 17 for x, y in [(row - 1, col), (row + 1, col), (row, col - 1), (row, col + 1)]: 18 if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1": 19 neighbors.append((x, y)) 20 grid[x][y] = "0" 21 return num_islands