您的位置:首页 > 其它

(LeetCode 64)Minimum Path Sum

2015-06-26 09:48 232 查看
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.

题目:

在一个m行n列的二维数组中,每个元素都是非负数,从左上角走到右下角,每次只能向右或向下走,求该路径的总和最小。

思路:

1、枚举

枚举所有路径,从左上角到右下角,共经过m+n-2步,其中向下走m-1步,向右走n-1步,因此所有可能路径数为C(m+n-2,m-1),算出所有路径的总和,找出最小的。

暴力枚举是万能的,但是不实际。

2、动态规划

假设dp[i][j]表示从左上角走到(i,j)的路径最小总和,因为每一步只能往下或往右,因此可以从左边(i-1,j)或上边(i,j-1)走到(i,j)。

状态转移方程:

dp[i][j]=min(dp[i-1][j],dp[i][j-1])+A[i][j]

初始值:

dp[0][0]=A[0][0],

dp[i][0]=dp[i-1][0]+A[i][0],

dp[0][j]=dp[0][j-1]+A[0][j].

复杂度:

时间复杂度O(m*n),空间复杂度O(m*n)

空间优化:

dp[i][j]=min(dp[i-1][j],dp[i][j-1]),只与dp[i-1][j],dp[i][j-1]有关,可以去掉一维,只剩下

dp[j]=min(dp[j],dp[j-1]),因为等号右边的dp[j]是旧的,即dp[i-1][j],等号右边的dp[j-1]是新的,即dp[i][j-1](从循环i,j中可以明显看出来)

代码:

class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size();
int n=grid[0].size();
vector<vector<int> > dp(m,vector<int>(n,0));

for(int i=0;i<m;i++){
for(int j=0;j<n;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[m-1][n-1];
}
};


class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size();
int n=grid[0].size();
vector<int> dp(n,0);

for(int i=0;i<m;i++){
for(int j=0;j<n;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[n-1];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: