Leetcode—最小路径和

本文介绍了LeetCode中关于找到网格中从左上角到右下角的最小路径和问题。通过解题思路分析,指出暴力递归会超时,推荐使用动态规划方法,类似于迪杰斯特拉算法,从第一个网格开始逐步计算每个网格的最短路径。并提供了样例输入和输出,以及解题代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最小路径和

【题目描述】

一个包含非负整数的 m*n 的网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。

样例输入:

[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。(官方题解)

【解题思路】

1:因为每个网格都有向下或向右2种选择(除了特殊边界), 每次均类似判断选最短的,联想到暴力递归, 但超时了。

2:动态规划, 大体思想类似于迪杰斯特拉算法求图中v0点到各点最短路径

​ 从第一个网格开始将各网格的值重新赋为左上角到该网格最短路径和, 而后面每个网格 (少数边界特殊考虑即可)

都可由其上网格或左网格选最小路径和加上原自身路径得到。

【vector用法补充】
1:定义二维vector数组   vector<vector<int> > A;

2:插入元素, 若想定义A = [[0,1,2],[3,4,5]],则:
vector<vector<int> > A;    //A.push_back里必须是vector
vector<int> B;
B.push_back(0);
B.push_back(1);
B.push_back(2);
A.push_back(B);
B.clear(); //记住要清除B
B.push_back(3);
B.push_back(4);
B.push_back(5);
A.push_back(B);

3:vector<vector<int> >A中的vector元素的个数
row = A.size();  //行数m
col = A[0].size  //列数n

4:访问元素,同二维数组类似
 cout << A[i][j] << " ";

【样例代码】
  • 1: 暴力递归

    // 方法1: 暴力求解法就是利用递归
    class Solution {
    public:
    	int minPathSum(vector<vector<int>>& grid) {
    		return sumMin(0, 0, grid);
    	}
    	int sumMin(int i, int j, vector<vector<int> > A)
    	{
    		int sum1 = 0, sum2 = 0; ///每次调用都要初始化//
    		int m = A.size(), n = A[0].size();   // m: 二维数组行数,  n: 二维数组列数
    		if (i<m-1)
    		{
    			sum1 += sumMin(i + 1, j, A) + A[i][j];   ///向下
    		}
    		if (j<n-1)
    		{
    			sum2 += sumMin(i, j + 1, A) + A[i][j];  ///向右
    		}
    		if (i == m-1 && j == n-1)  return A[m-1][n-1];  //仔细点 数组下标越界 0到m-1  0到n-1
    
    		if (sum1 == 0)  return sum2;  // sum1无路可通0,只有sum2所对应路径
    		else if (sum2 == 0)    return sum1;  // sum2无路可通0,只有sum1所对应路径
    		else   return sum1 < sum2 ? sum1 : sum2;  // 都有路时,选较短的
    	}
    };
    
    
  • 2: 动态规划

    class Solution {
    public:
    	int minPathSum(vector<vector<int>>& grid) {
    		int m = grid.size(), n = grid[0].size();
    
    		for (int i = 0; i < m ; i++)
    		{  动态规划, 每个位置上值都被重新赋为 从左上角到此位置路径最短之和
    			for (int j = 0; j < n; j++)
    			{   
    				if (i == 0 && j == 0) { grid[i][j] = grid[i][j]; }	
    				else if ( i == 0 && j != 0 )
    				{ // 到达第1列上只有由上到下的路径, 累加得到此位置最短路径和
    					grid[i][j] += grid[i][j - 1];
    				}
    				else if ( j == 0 && i != 0 )
    				{ // 第1行, 思路与列类似
    					grid[i][j] += grid[i - 1][j];
    				}
    				else 
    				{ // 求到达其它位置最短路径和:从它的左网格和上网格选出较小的再加上原来自身路径即可
    					grid[i][j] += grid[i - 1][j] < grid[i][j - 1] ? grid[i - 1][j] : grid[i][j - 1];
    				}
    			}
    		}
    		return grid[m - 1][n - 1] ;  
    	}
    };
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值