一、题目:矩阵最小路径
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小。
思路1:时间O(M*N),空间O(M*N)
新建一个矩阵dp(大小也是M*N),该矩阵是从上往下,从左往右记录每一步的结果的,当前的结果可以根据该矩阵上面和左边最小的值来获得,即:
dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j]
如:
grid = [ [1,3,1], |
dp = [[1,4,5], |
所以结果为dp[-1][-1] = 7
代码:
def minPathSum(self, grid): """ :type grid: List[List[int]] :rtype: int """ #使用二维数组 if not grid or not grid[0]: return 0 matrix = list(zip(*grid)) if len(grid) <= 1: return sum(grid[0]) if len(matrix) <= 1: return sum(matrix[0]) dp = [[0]*len(grid[0]) for i in range(len(grid))] dp[0][0] = grid[0][0] for i in range(1,len(grid)): dp[i][0] = grid[i][0] + dp[i-1][0] for j in range(1,len(grid[0])): dp[0][j] = grid[0][j] + dp[0][j-1] for i in range(1,len(grid)): for j in range(1,len(grid[0])): dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j] return dp[-1][-1]
思路2:时间O(M*N),空间O( min(M,N) )
新建一个列表dp(大小为min(M,N)),循环行数次更新记录每一行的路径值。
如:
grid =
[ [1,3,1],
[1,5,1],
[4,2,1]]
第一次更新:dp = [1,4,5]
第二次更新:dp = [2,7,6],比如:原本dp = [1,4,5],然后 先将 dp[0] 更新为2,然后dp[1] : 【min ( dp[0] 和dp [1] ) 与grid [1][1]相加之和】来更新 dp [1]
第三次更新:dp = [6,8,7]
更新是根据:
dp[j] = min(dp[j-1],dp[j]) + grid[i][j]
代码:
#使用一维数组 if not grid or not grid[0]: return 0 if len(grid) <= 1: return sum(grid[0]) if len(grid[0]) <= 1: return sum([val[0] for val in grid]) n = min(len(grid),len(grid[0])) m = len(grid) if n == len(grid[0]) else len(grid[0]) dp = [0] * n dp[0] = grid[0][0] if n == len(grid): grid = list(zip(*grid)) for i in range(1,n): dp[i] = grid[0][i] + dp[i-1] for i in range(1,m): for j in range(n): dp[j] = min(dp[j-1],dp[j]) + grid[i][j] if j>=1 else dp[j] + grid[i][j] return dp[-1]
原文地址:https://www.cnblogs.com/Lee-yl/p/9973770.html
时间: 2024-10-08 10:19:36