题目
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
用宽度优先搜索思想,将一个根节点(取值为1)相邻(这里指在水平或竖直方向相邻的1)的节点全部放入队列,并遍历队列中所有节点做相同操作,对于每一个从队列中取出的节点,将其值置为0,表示已经访问过。在外层套两个循环用于遍历二维数组,每发现一个根节点,就对它启动宽度优先搜索,且nums加1,最后返回nums就是岛屿数量。
1.宽度优先搜索(BFS)
时间复杂度O(n*m),空间复杂度O(min(n,m)) ,击败94%
class Solution:
def __init__(self):
self.queue = []
self.visited = []
self.nums = 0
def numIslands(self, grid: List[List[str]]) -> int:
if grid == []:
return 0
x_len = len(grid)
y_len = len(grid[0])
for i in range(x_len):
for j in range(y_len):
if grid[i][j] == '1':
self.queue.append((i,j))
grid[i][j] = '0'
self.nums += 1
while self.queue:
x,y = self.queue.pop(0)
if (x-1>=0) and (grid[x-1][y] == '1'):
self.queue.append((x-1,y))
grid[x-1][y] = '0'
if (x+1<x_len) and (grid[x+1][y] == '1'):
self.queue.append((x+1,y))
grid[x+1][y] = '0'
if (y-1>=0) and (grid[x][y-1] == '1'):
self.queue.append((x,y-1))
grid[x][y-1] = '0'
if (y+1<y_len) and (grid[x][y+1] == '1'):
self.queue.append((x,y+1))
grid[x][y+1] = '0'
return self.nums
2.深度优先搜索(DFS)
定义一个cov函数,用来传播’病毒‘,这也是它叫cov的原因,害怕.jpg
1表示健康人,0表示被感染者
从开头遍历grid,当元素=1时,将此处坐标传入cov,病毒通过DFS传播,直到其附近都为’0‘时,才停止传播。
统计调用了cov几次,就代表有几个岛屿(几个健康人集群)
时间复杂度O(n * m),空间复杂度O(n * m) 击败94%
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def cov(node:list):
i, j = node
if i-1 >= 0 and grid[i-1][j] == '1':
grid[i-1][j] = '0'
cov([i-1,j])
if i+1 < len(grid) and grid[i+1][j] == '1':
grid[i+1][j] = '0'
cov([i+1,j])
if j-1 >= 0 and grid[i][j-1] == '1':
grid[i][j-1] = '0'
cov([i,j-1])
if j+1 < len(grid[0]) and grid[i][j+1] == '1':
grid[i][j+1] = '0'
cov([i,j+1])
nums = 0
if grid == []:
return 0
for x in range(len(grid)):
for y in range(len(grid[0])):
if grid[x][y] == '1':
nums += 1
cov([x, y])
return nums