64. 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.

这是一道经典的动态规划问题。解法很简单,如下:
如果我们设置dp数组的时候每个维度多一维就可以不用考虑边界条件了。

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));//不用考虑边界条件
        dp[0][1] = 0; dp[1][0] = 0;
        for(int i =1; i<= m;i++){
            for(int j =1 ; j<= n;j++){
                dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1];  //这里是i-1 和 j-1  !!!!!
            }
        }
        return dp[m][n];
    }
};

 

显然我们在求dp[i][j]的时候是只需要dp[i-1][j]dp[i][j-1] 的,所以我们是没有必要这么大一个m*n的矩阵的,我们可以只维护两个列即可。
解法二:

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

 

然后我们又发现pre这个数组其实也是没有必要维护的,因为我们只是在更新cur数组的时候用到了而已。
解法三:

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

 

posted @ 2016-03-30 14:08  背锅侠  阅读(205)  评论(0编辑  收藏  举报