算法52-----矩阵最小路径【动态规划】

一、题目:矩阵最小路径

给定一个包含非负整数的 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],
  [1,5,1],
  [4,2,1]]


dp =

[[1,4,5],
  [2,7,6],
  [6,8,7]]

所以结果为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

算法52-----矩阵最小路径【动态规划】的相关文章

代码题(34)— 矩阵最小路径和

1.64. 最小路径和 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 需要用动态规划Dynamic Programming来做,这应该算是DP问题中比较简单的一类,我们维护一个二维的dp数组,其中dp[i][j]表示当前位置的最小路径和,递推式也容易写出来 

力扣算法题—064最小路径之和

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 1 #include "_000库函数.h" 2 3 //使用Dijkstra算法 4 //即动态规划 5 class Solution { 6 public: 7 int minPathSum(vec

【数据结构与算法】动态规划——最小路径和(普通矩阵、三角形两题)

最小路径和 LeetCode:最小路径和 题目描述: 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 思想: 动态规划,可以用原数组作为dp数组 代码: class Solution { public int minPathSum(int[][] grid) {

矩阵的最小路径和二维动态规划的空间压缩

题目:给定一个矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,路径上的所有的数字累加起来作为这条路径的路劲和.要求返回所有路径和中的最小路径和. 举例: 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回其和12. 解析: 这个题目很类似之前的那个动态规划的数字三角的问题.毫无疑问的,这个问题也是用动态规划解决.只要确定了状态和转移方程,这个题目很容易解决.下面直接给出代码: //利用path记录路径,对于每一个path[i][j],0代表dp[i][j]的值从上

【动态规划专题】2:矩阵的最小路径和

<程序员代码面试指南--IT名企算法与数据结构题目最优解> 左程云 著 矩阵的最小路径和 [题目]给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角位置,路径上所有的数字累加起来就是路径和,返回所有路径中最小的路径和. [举例]如果给定的m如下:1 3 5 98 1 3 45 0 6 18 8 4 0路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12. 关键思路:假设有一个M*N的数组 dp[M][N], dp[i][j]的值表示从左上角(0,0)位置走到(i

算法学习——动态规划之点数值三角形的最小路径

算法描述 在一个n行的点数值三角形中,寻找从顶点开始每一步可沿着左斜或者右斜向下直到到达底端,使得每个点上的数值之和为最小 右图为一个4行的点数值三角形 算法思路 接收用户输入行数n 使用一个二维数组a[n+1][n+1]来存放各个点上的数值,数值可以由用户输入或者是随机生成 定义一个二维数组(用来存放方向)direction[n+1][n+1],存放1或0,1代表右,0代表左 定义一个二维数组b[n+1][n+1] 表示到底端的数值之和 以上图4行的点数值三角形为例 b[4][1]=47 b[

LeetCode—Minimum Path Sum 二维数组最小路径,动态规划

感觉这是一系列的动态规划的算法,正好也将动态规划的算法进行一个总结: 算法一: 带权重的最小路径的问题 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. 首先每一个路径的上一个路径都是来自于其上方和左方 现将最上面的路径进行求和,最左边的路径进行求和

矩阵中的最小路径

package 数阵中的最优路径; import java.util.Scanner; public class Main2 { /** * 数阵中的最小路径搜索 * 1:设计要点 * 应用动态规划设计从右下角逐行至左上角,确定n,m后,随机产生的整数二维数组a(n,m)作矩阵输出同时赋值给部分和数组b(n,m). * 数组b(i,j)为点(i,j)到到右下角的最小数值和stm(i,j)是点(i,j)向右(R)或向下(D)或向右下(0)的路标数组 * 注意到最后一行与最后一列各数只有一个出口,于

#动态规划 LeetCode 120 三角形最小路径和

给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11). 说明: 如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分. 思路: 接着上一题的状态转移继续说 动态规划问题,重中之重就是找到状态转移方程,而状态转移方程很重要的一点就是明确函数的意义所在,以及记录结果