给定一个包含非负整数的 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
使用贪心加动态规划的思路
以数组dp[i][j]表示:走到位置i,j的最小路径花费
有如下状态转移方程:
dp[i][j]=min(dp[i−1][j]+grid[i][j],dp[i][j−1]+grid[i][j])dp[i][j]=min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j]) dp[i][j]=min(dp[i−1][j]+grid[i][j],dp[i][j−1]+grid[i][j])
即dp[i][j]是从左边临近位置走来的路径花费和从上边临近位置走来的路径花费比较中的最小者。
根据此状态转移方程,并给dp[0][0]赋初始值为grid[0][0]
我们就可以依次求得走到每一个位置的最小路径花费,从而最终求得终点的最小路径花费
时间复杂度为O(mn)
空间复杂度为O(mn),这里也可以考虑直接修改原矩阵将空间复杂度降低至O(1)
int minPathSum(int** grid, int gridSize, int* gridColSize){int m=gridSize,n=*gridColSize;int dp[m][n];int i,j,a,b;dp[0][0]=grid[0][0];for(i=0;ifor(j=0;ja=99999;b=999999;if(i!=0||j!=0){if(i>0) a=dp[i-1][j]+grid[i][j];if(j>0) b=dp[i][j-1]+grid[i][j];dp[i][j]=fmin(a,b);}}}return dp[m-1][n-1];
}
上一篇:日期类的实现