📅  最后修改于: 2023-12-03 15:12:43.216000             🧑  作者: Mango
题目描述:
给定一个二维布尔数组,表示一个0和1的网格图。一个组被定义为在所有相邻的1之间构成的集合。一个1与其四联通的1是相邻的。找到并返回该网格图中组的数目。
示例:
输入:
00110 01110 00101 00011
输出:3
解释:图中有3个组。第一个组是{(0,0), (0,1), (1,2), (1,3), (2,2)}, 第二个组是{(2,0)}, 第三个组是{(3,3), (2,4)}
解决方案:
这个问题可以通过深度优先搜索(DFS)算法解决。
DFS是用于遍历或搜索树或图的算法。在图的情况下,DFS从任意节点开始遍历,随机选择一个相邻的未被访问的节点。然后继续对该节点进行DFS,直到所有节点都被访问。
所以,我们可以遍历这个网格图,如果当前节点是1,我们就用DFS找到该节点属于哪个组,并标记访问过的位置。将所有属于同一个组的节点都标记成已访问,然后计数器加1。最后,返回计数器的值即可。
以下是Python代码的实现:
def numIslands(grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
count += 1
dfs(grid, i, j) # 找到当前节点属于哪个组的dfs
return count
def dfs(grid, row, col):
"""
:type grid: List[List[str]]
:type row: int
:type col: int
"""
if row < 0 or col < 0 or row >= len(grid) or col >= len(grid[0]) or grid[row][col] != '1':
return
grid[row][col] = '#' # 标记为已访问
# 向四周扩展
dfs(grid, row - 1, col)
dfs(grid, row + 1, col)
dfs(grid, row, col - 1)
dfs(grid, row, col + 1)
其中,numIslands函数遍历每个节点并计算组数。如果一个节点是1,它调用dfs函数找到该1的组,并将所有属于同一组的节点标记为已访问。
dfs函数朝四个方向扩展,找到相邻的1,并标记为已访问。
最后返回组数。
这是一个时间复杂度为O(m*n)的解决方案,其中m和n分别是网格图的行数和列数。
附:使用Python类中的DFS方法
在Python中,你还可以使用类中的DFS方法解决这个问题。
首先,我们创建一个类,名为Solution。然后,我们定义一个访问组的dfs函数,并在init函数中定义一个组计数器。最后,在numIslands函数中遍历每个位置,并调用dfs函数处理每个未访问的1。
以下是Python代码的实现:
class Solution:
def __init__(self):
self.count = 0
def numIslands(self, grid: List[List[str]]) -> int:
if not grid:
return 0
for row in range(len(grid)):
for col in range(len(grid[0])):
if grid[row][col] == '1':
self.count += 1
self.dfs(grid, row, col)
return self.count
def dfs(self, grid, row, col):
if row < 0 or col < 0 or row >= len(grid) or col >= len(grid[0]) or grid[row][col] != '1':
return
grid[row][col] = '#' # 标记为已访问
self.dfs(grid, row - 1, col)
self.dfs(grid, row + 1, col)
self.dfs(grid, row, col - 1)
self.dfs(grid, row, col + 1)
注意,这个方法需要导入一个名为List的类型提示。List是一个Python的泛型,它指定了列表所有元素的类型。
这是一个时间复杂度为O(m*n)的解决方案,其中m和n分别是网格图的行数和列数。