题目描述
自己解法
广度优先遍历(BFS),使用列表queue
模拟队列
,isSelected矩阵
存储该点是否被遍历过。时间复杂度
O
(
m
∗
n
)
O(m*n)
O(m∗n),空间复杂度
O
(
m
∗
n
)
O(m*n)
O(m∗n)
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
isSelected = [[False for line in row]for row in grid]
count = 0
queue = []
for i in range(len(grid)):
for j in range(len(grid[0])):
if not isSelected[i][j]:
isSelected[i][j] = True
if grid[i][j] == '1':
queue.append((i,j))
while queue:
x,y = queue.pop(0)
for k,m in zip((x-1,x+1,x,x),(y,y,y-1,y+1)):
if 0 <= k < len(grid) and 0 <= m < len(grid[0]):
if isSelected[k][m] == False:
isSelected[k][m] = True
if grid[k][m] == '1':
queue.append((k,m))
count += 1
return count
对比题解区后,发现上述代码有两个缺点:
- 使用列表模拟队列,效率低
- isSelected矩阵耗费空间巨大
改进方法:
- 使用collections中的deque来实现队列
- 不使用矩阵存储遍历信息,而是对于遍历过的“1”,都置为“0”,这样也可判断该点是否遍历过
改进后的代码为:
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
count = 0
queue = deque()
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
queue += [(i,j)]
count += 1
while queue:
x,y = queue.popleft()
for k,m in [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]:
if 0 <= k < len(grid) and 0 <= m < len(grid[0]):
if grid[k][m] == '1':
grid[k][m] = '0'
queue.append((k,m))
return count
时间复杂度
O
(
m
∗
n
)
O(m*n)
O(m∗n),空间复杂度
O
(
m
i
n
[
m
,
n
]
)
O(min[m,n])
O(min[m,n])。
题解区
本题的另外两个解法是深度优先遍历
和并查集
,详见官方解答。