LeetCode-64. 最小路径和【数组 动态规划 矩阵】

LeetCode-64. 最小路径和【数组 动态规划 矩阵】

题目描述:

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]

输出:7

解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]

输出:12

提示:

m == grid.length

n == grid[i].length

1 <= m, n <= 200

0 <= grid[i][j] <= 200

此题解法与LeetCode-62. 不同路径【数学 动态规划 组合数学】非常相似!

解题思路一:动态规划五部曲。定推初遍举

  1. 确定dp数组(dp table)以及下标的含义

    dp[i][j] :表示从左上角出发到 (i,j) 位置的最小路径和。

  2. 确定递推公式

    想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。

此时在回顾一下 dp[i - 1][j] 表示啥,是从(0, 0)的位置到(i - 1, j)的最小路径和,dp[i][j - 1]同理。

那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。

  1. dp数组的初始化
    如何初始化呢,首先dp[0][0] = grid[0][0],从(0, 0)的位置到(i, 0)的路径就是相加即可,那么dp[0][j]也同理。
python 复制代码
dp[0][0] = grid[0][0]
for i in range(1, m):
    dp[i][0] = dp[i-1][0] + grid[i][0]
for j in range(1, n):
    dp[0][j] = dp[0][j-1] + grid[0][j]
  1. 确定遍历顺序
    这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。

这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。

  1. 举例推导dp数组
    如图所示:
python 复制代码
class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        dp = [[0] * n for _ in range(m)]
        dp[0][0] = grid[0][0]
        for i in range(1, m):
            dp[i][0] = dp[i-1][0] + grid[i][0]
        for j in range(1, n):
            dp[0][j] = dp[0][j-1] + grid[0][j]
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = min(grid[i][j] + dp[i-1][j], grid[i][j] + dp[i][j-1])
        return dp[-1][-1]

时间复杂度:O(nm)

空间复杂度:O(nm)

解题思路二:动态规划优化空间,直接改grid

python 复制代码
class Solution:
    def minPathSum(self, grid: [[int]]) -> int:
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if i == j == 0: continue
                elif i == 0:  grid[i][j] = grid[i][j - 1] + grid[i][j]
                elif j == 0:  grid[i][j] = grid[i - 1][j] + grid[i][j]
                else: grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j]
        return grid[-1][-1]

时间复杂度:O(nm)

空间复杂度:O(1)

解题思路三:dfs

python 复制代码
class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        @cache
        def dfs(m,n):
            if m==0 and n ==0:
                return grid[m][n]
            if m==0:
                return dfs(m,n-1)+grid[m][n]
            if n==0:
                return dfs(m-1,n)+grid[m][n]
            return min(dfs(m-1,n),dfs(m,n-1))+grid[m][n]
        return dfs(m-1,n-1)

时间复杂度:O(nm)

空间复杂度:O(nm)

相关推荐
aigcapi3 小时前
RAG 系统的黑盒测试:从算法对齐视角解析 GEO 优化的技术指标体系
大数据·人工智能·算法
柯慕灵4 小时前
7大推荐系统/算法框架对比
算法·推荐算法
adam-liu4 小时前
Fun Audio Chat 论文+项目调研
算法·语音端到端·fun-audio-chat
栀秋6664 小时前
你会先找行还是直接拍平?两种二分策略你Pick哪个?
前端·javascript·算法
.魚肉5 小时前
旅行商问题 (TSP)的蛮力算法与动态规划算法(Held-Karp)
动态规划·算法设计与分析·tsp·旅行商问题·蛮力法·held-karp算法·复杂度求解
如果你想拥有什么先让自己配得上拥有5 小时前
数学思想和数学思维分别都有什么?
线性代数·算法·机器学习
长安er5 小时前
LeetCode136/169/75/31/287 算法技巧题核心笔记
数据结构·算法·leetcode·链表·双指针
MarkHD5 小时前
智能体在车联网中的应用:第29天 多智能体完全合作场景的核心算法:从CTDE思想到VDN与MADDPG的深度解析
算法
wanzhong23336 小时前
CUDA学习5-矩阵乘法(共享内存版)
深度学习·学习·算法·cuda·高性能计算
fufu03116 小时前
Linux环境下的C语言编程(四十八)
数据结构·算法·排序算法