剑指 Offer II 099. 最小路径之和
一、题目
1.题目描述
给定一个包含非负整数的 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] <= 100
2.基础框架
C++基础框架代码如下:
int minPathSum(vector<vector<int> >& grid){
}
3.解题思路
- 题目分析
- 题目目标是返回从左上角到右下角的路径上的数字的最小总和。
- 这道题是求最值问题,可以考虑动态规划。
- 除0行0列之外的
dp[i][j]
可由dp[i - 1][j]
或dp[i][j - 1]
转移过来,所以我们可以得到的递归公式为:dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
dp[i][j]
表示i,j当前的位置所走的最小路径总和。- 因为
dp[i][j]
状态由dp[i - 1][j]和dp[i][j - 1]
转移而来,我们要对i为0和j为0这两种情况进行初始化。 i = 0
的时候,表示只有一条路径,所以i = 0
这一行中的每一列初始化为当前从左往右所走路径的数字累加和,j = 0
这一列中的每一行也要初始化为从上往下所走路径的数字累加和。
-
实现代码:
int minPathSum(vector<vector<int>>& grid) { int m = grid.size(); int n = grid[0].size(); vector<vector<int> > dp(m, vector<int>(n)); dp[0][0] = grid[0][0]; // 初始化(0,0)位置的最小值 for (int i = 1; i < m; i++) // 初始化第0列除(0,0)位置的路径和最小值 dp[i][0] = grid[i][0] + dp[i - 1][0]; for (int j = 1; j < n; j++) // // 初始化第0行除(0,0)位置的路径和最小值 dp[0][j] = grid[0][j] + dp[0][j - 1]; for (int i = 1; i < m; i++) for (int j = 1; j < n; j++) dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; return dp[m - 1][n - 1]; }