给定一个包含非负整数的 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
dp题解
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size(); //行
int n = grid[0].size(); //列
//定义数组时,行和列多定义一行,防止超范围
//而没有定义的地方都是INT_MAX
vector<vector<int>> dp(m+1, vector<int>(n+1, INT_MAX)); // dp[i+1][j+1]表示到达grid[i][j]的最小路径和
//这样就以这个数组的(1,1)为原数组的起始点
dp[0][1] = dp[1][0] = 0; // 特殊处理处理dp[1][1]的左侧和上侧的状态,保证dp[1][1]=grid[0][0]
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
//主要就只看左边和上边
dp[i+1][j+1] = min(dp[i+1][j], dp[i][j+1]) + grid[i][j];
}
}
return dp[m][n];
}
};
刚开始dp出错
又用bfs当成岛屿问题做
方法选择错误
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int n = grid.size();
int m=grid[0].size();
vector<vector<int>> f(n, vector<int>(m));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
f[i][j]=1000;
bfs(0,0,f,grid,n,m);
// for (int i = 0; i < n; ++i)
// for (int j = 0; j < m; ++j){
// if(i-1>0){
// f[i-1][j]=min(grid[i][j]+grid[i-1][j],f[i-1][j]);
// }
// if(i+1<n){
// f[i+1][j]=min(grid[i][j]+grid[i+1][j],f[i+1][j]);
// }
// if(j-1>0){
// f[i][j-1]=min(grid[i][j]+grid[i][j-1],f[i][j-1]);
// }
// if(j+1<m){
// f[i][j+1]=min(grid[i][j]+grid[i][j+1],f[i][j+1]);
// }
// }
return f[n-1][m-1];
}
void bfs(int i,int j,vector<vector<int>>& f,vector<vector<int>>& grid,int n,int m){
if(i-1>0){
f[i-1][j]=min(grid[i][j]+grid[i-1][j],f[i-1][j]);
bfs(i-1,j,f,grid,n,m);
}
if(i+1<n){
f[i+1][j]=min(grid[i][j]+grid[i+1][j],f[i+1][j]);
bfs(i+1,j,f,grid,n,m);
}
if(j-1>0){
f[i][j-1]=min(grid[i][j]+grid[i][j-1],f[i][j-1]);
bfs(i,j-1,f,grid,n,m);
}
if(j+1<m){
f[i][j+1]=min(grid[i][j]+grid[i][j+1],f[i][j+1]);
bfs(i,j+1,f,grid,n,m);
}
}
};