您的位置:首页 > 其它

leetcode-64-Minimum Path Sum

2015-07-08 19:06 453 查看


Minimum Path Sum



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.
一个二维数组,求从左上角到右下角, 最小的长度。每个元素都是非负整数,只能向走右或向下走。




DFS

需要优化,否则TLE
int solve(int** a,int n,int m,int x,int y,int s[1000][1000]){  // 从(x,y)走到最右下角的最小和
if(x==n||y==m) return 0; // 若走"出界",则返回 0
if(s[x][y]!=-1) return s[x][y]; // 优化,   s[x][y]代表点(x,y)到最右下角的最小和。初值为-1。

int w1=solve(a,n,m,x+1,y,s); // w1为向下走的最小和
int w2=solve(a,n,m,x,y+1,s); // w2为向右走的最小和

/*然后比较w1与w2的大小,选小的*/

// 到"边界"要分情况,因为“出边界”的点返回0,我们又找的是最小值,所以我们会找到出边界的点,即0,但实际上不能选哪个店。
if(x+1==n&&y+1<m) s[x][y]=a[x][y]+w2;
else if(x+1<n&&y+1==m) s[x][y]=a[x][y]+w1;
else if(x+1<n&&y+1<m) s[x][y]=a[x][y]+(w1<w2?w1:w2);  // 注意加 括号 T_T
else s[x][y]=a[x][y];

return s[x][y];
}

int minPathSum(int** grid, int gridRowSize, int gridColSize) {
int s[1000][1000];
memset(s,-1,sizeof(s));// 初始化为-1
return solve(grid,gridRowSize,gridColSize,0,0,s);
}


因为要找最小值,所以在边界,可以返回一个无穷大的值,这样肯定就不会选到出界的点

int solve(int** a,int n,int m,int x,int y,int s[1000][1000]){
if(x==n||y==m) return 0x3fffff; // 返回一个"无穷大"的值
if(s[x][y]!=-1) return s[x][y]; // 优化
if(x==n-1&&y==m-1) return s[x][y]=a[x][y]; // 在最后一个点时,避免两个无穷大的值比较  就直接输出

int w1=solve(a,n,m,x+1,y,s);
int w2=solve(a,n,m,x,y+1,s);
s[x][y]=a[x][y]+(w1<w2?w1:w2);// 选择最小的和           注意加 括号 T_T
return s[x][y];
}

int minPathSum(int** grid, int gridRowSize, int gridColSize) {
int s[1000][1000];
memset(s,-1,sizeof(s));
return solve(grid,gridRowSize,gridColSize,0,0,s);
}






DP




参考七月算法-动态规划




s[i][j]表示从左上到达(i,j)的最小值,s[i][j]从上面来(s[i][j]=s[i-1][j]+a[i][j]),或从左边来(s[i][j]=s[i][j-1]+a[i][j])。


所以 s[i][j]=min(s[i][j-1],s[i-1][j])+a[i][j]




C语言


int minPathSum(int** grid, int gridRowSize, int gridColSize) {
int s[1000][1000]; // s[x][y] 为 点(0,0)到点(x,y)的最小和

s[0][0]=grid[0][0];            // 第一个元素
for(int i=1;i<gridRowSize;i++) // 除一个元素以外的 第一列
s[i][0]=grid[i][0]+s[i-1][0];
for(int j=1;j<gridColSize;j++) // 除一个元素以外的 第一行
s[0][j]=grid[0][j]+s[0][j-1];

for(int i=1;i<gridRowSize;i++)
for(int j=1;j<gridColSize;j++){
s[i][j]=grid[i][j]+(s[i-1][j]<s[i][j-1]?s[i-1][j]:s[i][j-1]);
}
return s[gridRowSize-1][gridColSize-1];
}




c++


class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int n = grid.size(),m = grid[0].size();
vector<vector<int> >dp(n,vector<int>(m));
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++){
if (i == 0) {
if (j == 0) dp[i][j] = grid[i][j];
else dp[i][j] = dp[i][j - 1] + grid[i][j];
}
else if (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[n - 1][m - 1];
}
};






可以进行空间优化
对每个i,正向循环j

dp[j]=min(dp[j - 1],dp[j])+grid[i][j];
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int n = grid.size(),m = grid[0].size();
vector<int>dp(m);
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++){
if (i == 0) {
if (j == 0) dp[j] = grid[i][j];
else dp[j] = dp[j - 1] + grid[i][j];
}
else if (j == 0) dp[j] = dp[j] + grid[i][j];
else
dp[j] = min(dp[j],dp[j - 1]) + grid[i][j];
}
return dp[m - 1];
}
};


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: