Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Example 1:
[[1,3,1], [1,5,1], [4,2,1]]Given the above grid map, return
7
. Because the path 1→3→1→1→1 minimizes the sum.
方法一:
采用递归调用的思想,从左上角开始,每次往右或者下进行移动,到达右下角后,保存结果,然后进行回溯。代码如下,可惜超时:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
if(grid.empty() || grid[0].empty())
return 0;
int res = INT_MAX;
m = grid.size();
n = grid[0].size();
dfs(grid, 0, 0, res, 0);
return res;
}
void dfs(vector<vector<int>>& grid, int i, int j, int& res, int tmp) {
tmp += grid[i][j];
if(i == m-1 && j == n-1) {
res = min(res, tmp);
}
if(i < m-1) {
dfs(grid, i+1, j, res, tmp);
}
if(j < n-1) {
dfs(grid, i, j+1, res, tmp);
}
}
private:
int m, n;
};
方法二:
采用DP动态规划,定义dp[i][j]数组为从左上角(0, 0)到位置(i, j)的最短路径,则:
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
当i=0,或j=0时,则分别为:
dp[i][j] = dp[i][j-1] + grid[i][j]
dp[i][j] = dp[i-1][j] + grid[i][j]
代码如下:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
if(grid.empty() || grid[0].empty())
return 0;
int m = grid.size();
int n = grid[0].size();
int dp[m][n] = {0};
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(i == 0 && j == 0) {
dp[i][j] = grid[i][j];
}
else if(i == 0 && j != 0) {
dp[i][j] = dp[i][j-1] + grid[i][j];
}
else if(i != 0 && j == 0) {
dp[i][j] = dp[i-1][j] + grid[i][j];
}
else {
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
}
}
}
return dp[m-1][n-1];
}
};