【动态规划】力扣542:01矩阵
给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例:
输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]
一般来说,因为这道题涉及到四个方向上的最近搜索,所以很多人的第一反应可能会是广度优先搜索。但是对于一个大小 O(mn) 的二维数组,对每个位置进行四向搜索,最坏情况的时间复杂度(即全是 1)会达到恐怖的 O(m2n2)。可以使用一个 dp 数组做 memoization,使得广度优先搜索不会重复遍历相同位置.
另一种更简单的方法是,先从左上到右下进行一次动态搜索,即完成左、上两个方向的查找;再从右下到左上进行一次动态搜索,即完成右、下两个方向的查找。两次动态搜索即可完成四个方向上的查找。
class Solution:
def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
if not matrix:
return 0
m, n = len(matrix), len(matrix[0])
dp = [[10**4] * n for _ in range(m)]
# 第一次查找
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
dp[i][j] = 0
if i > 0:
dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1)
if j > 0:
dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1)
# 第二次查找
for i in range(m - 1, -1, -1):
for j in range(n - 1, -1, -1):
if i < m - 1:
dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1)
if j < n - 1:
dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1)
return dp
时间复杂度:O(mn),其中 m 为矩阵行数,n 为矩阵列数。计算 dp 数组的过程中需要遍历两次矩阵,因此时间复杂度为 O(2mn)=O(mn)。
空间复杂度:O(1),只计算额外的空间复杂度。除了答案数组以外,只需要常数空间存放若干变量。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理