关闭

leetcode-64-Minimum Path Sum

标签: leetcodeDP
370人阅读 评论(0) 收藏 举报
分类:

                                                 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];
    }
};





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:56787次
    • 积分:2029
    • 等级:
    • 排名:第18973名
    • 原创:148篇
    • 转载:11篇
    • 译文:0篇
    • 评论:0条