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