📅  最后修改于: 2023-12-03 15:42:20.394000             🧑  作者: Mango
本题考察迭代算法。题目描述如下:
给定一个M*N的01矩阵,每个位置要么是0要么是1。现在定义一个操作,将一个0变成1并将与它相邻的1改为0。问最少需要执行多少次操作才能使整个矩阵中的全部0变为1。
例如,对于下面的4*4矩阵:
1 0 0 1
0 0 1 0
0 0 0 0
1 0 0 1
最少需要执行3次操作才能使全部0变成1。一种可行的方案如下(第1次操作将右上角的0变为了1,第2次操作将右下角的0变为了1,第3次操作将左下角的0变为了1):
1 1 1 1
0 0 0 0
0 0 0 0
1 1 1 1
请实现以下函数:
def min_ops(matrix: List[List[int]]) -> int:
pass
函数参数是一个M*N的01矩阵;函数返回值是最少需要执行多少次操作才能使整个矩阵中的全部0变为1。
使用迭代算法求解。每一次从矩阵中找到一个0,并将它与相邻的1一起修改。修改的过程可以采用DFS或BFS。
我们可以构建一个队列,将每一次操作的结果放入队列。如果队列中存在所有元素都是1的矩阵,则说明操作结束。
具体步骤如下:
from typing import List
def min_ops(matrix: List[List[int]]) -> int:
# 构造四联通坐标偏移数组
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
m, n = len(matrix), len(matrix[0])
queue = []
def bfs(matrix: List[List[int]]) -> List[List[int]]:
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
# 将0元素的坐标加入列表中
queue.append((i, j))
step = 0
while queue:
# 记录队列长度,即本轮需要修改的元素个数
size = len(queue)
# 本轮修改的元素个数加入step
step += 1
for i in range(size):
x, y = queue.pop(0)
matrix[x][y] = 1
# 四联通判断
for dx, dy in directions:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n and matrix[nx][ny] == 1:
matrix[nx][ny] = 0
queue.append((nx, ny))
# 如果此时矩阵内全是1,则返回step
if all(all(row) for row in matrix):
return step
return -1
return bfs(matrix)
由于每个元素只会被修改一次,因此时间复杂度为$O(mn)$,其中m和n分别为矩阵的行数和列数。
空间复杂度为$O(mn)$,其中m和n分别为矩阵的行数和列数,主要是存储列表和队列所占用的空间。