192、【动态规划】leetcode ——64. 最小路径和:回溯法+动态规划(C++/Python版本)

文章介绍了如何解决64.最小路径和问题。首先提到了使用回溯法的解题思路,但由于会超时,所以转向了动态规划方法。动态规划通过递推公式dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]计算到达每个位置的最短路径,并初始化边界条件。最后,按照从上到下,从左到右的顺序遍历,得出终点的dp值。
摘要由CSDN通过智能技术生成

题目描述

在这里插入图片描述
在这里插入图片描述
原题链接:64. 最小路径和

解题思路

(1)回溯法

分别向右或下进行探查

class Solution {
public:
    int res = INT_MAX;
    void backtracking(vector<vector<int>>& grid, int x, int y, int pathSum) {
    	// 超出边界,返回
        if(x >= grid.size() || y >= grid[0].size())           return ;
        pathSum += grid[x][y];
        if(x == grid.size() - 1 && y == grid[0].size() - 1) {
            res = min(res, pathSum);
            return ;
        }

        for(int i = x; i < grid.size(); i++) {
            for(int j = y; j < grid[0].size(); j++) {
                backtracking(grid, x + 1, y, pathSum);            
                backtracking(grid, x, y + 1, pathSum);
            }
        }
    }
    int minPathSum(vector<vector<int>>& grid) {
        backtracking(grid, 0, 0, 0);
        return res;
    }
};

此方式会超时。

(2)动态规划

对于二维数组求最优解,常用的方式就是递归+备忘录,也就是动态规划,而递归可以用迭代实现。

  • 动态规划五步曲:

(1)dp[i][j]: 到达(i, j)处时,最短路径的长度

(2)递推公式: d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + g r i d [ i ] [ j ] dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] dp[i][j]=min(dp[i1][j],dp[i][j1])+grid[i][j],因为只能往右或下走,因此到达(i, j)处时,只可能有两条路过来,此时就找已有的两条路中最短路径的那一条。

(3)dp数组初始化: dp[i][0] = dp[i - 1][0] + grid[i][0] , , dp[0][j] = dp[0][j - 1] + grid[0][j],边界上只会顺着一条路走下来,这一种情况(因为只能往下或者往右走)。dp[0][0] = grid[0][0]。

(4)遍历顺序: 从上到下,从左到右,一步一步逼近终点。

(5)举例: (省略)

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        vector<vector<int>> dp(n, vector<int>(m));
        dp[0][0] = grid[0][0];
        for(int i = 1; i < n; i++)          dp[i][0] = dp[i - 1][0] + grid[i][0];
        for(int i = 1; i < m; i++)          dp[0][i] = dp[0][i - 1] + grid[0][i];

        for(int i = 1; i < n; i++) {
            for(int j = 1; j < m; j++) {
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }

        return dp[n - 1][m - 1];
    }
};

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 i in range(1, n):
            dp[0][i] = dp[0][i - 1] + grid[0][i]
        
        
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
        
        return dp[m - 1][n - 1]



参考文章:64. 最小路径和最小路径和动态规划之最小路径和

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值