LeetCode刷题笔记 - 64

64 - 动态规划

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.

Example:

Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7


Explanation: Because the path 1→3→1→1→1 minimizes the sum.

class Solution {
public:
int minPathSum(vector<vector<int> >& grid) {
int m = grid.size(), n = grid[0].size();
vector<vector<int> > dp(m, vector<int>(n)); // m rows, n cols
// Recursive formula： dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
// The initial value：
//     dp[0][0] = grid[0][0]
//     dp[0][j > 0] = dp[0][j-1] + grid[i][j]
//     dp[i > 0][j] = dp[i-1][0] + grid[i][j]
// Complexity: Time: O(m*n), Space: O(m * n)
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][j - 1], dp[i - 1][j]) + grid[i][j];
}
}
return dp[m-1][n-1];
}
};


1. dp[i][j] 只与dp[i-1][j]dp[i][j-1]有关；
2. 对每一个i，正向循环j
• dp[j-1]不断更新，dp[j]还是旧的
• dp[j] = min(dp[j-1], dp[j]) + grid[i][j] 这样省掉了第一维
其实就是我们不需要维护完整的m*n矩阵。维护两列就足够了，现在我们有了以下代码。
       int m = grid.size(), n = grid[0].size();
vector<int> dp(n);
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 - 1], dp[j]) + grid[i][j];
}
}
}
return dp[n - 1];


`