leetcode 64. 最小路径和
挺简单的
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,0));//dp[i][j]表示从grid[0][0]到grid[i][j]的最小路径
dp[0][0] = grid[0][0];
for(int i = 1;i < m;++i) dp[i][0] = dp[i-1][0] + grid[i][0];
for(int i = 1;i < n;++i) dp[0][i] = dp[0][i-1] + grid[0][i];
for(int i = 1;i < m;++i){
for(int j = 1;j < n;++j){
dp[i][j] = grid[i][j] + min(dp[i-1][j],dp[i][j-1]);
}
}
return dp[m-1][n-1];
}
};
灵神题解:
法一:
// 会超时的递归写法
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i < 0 || j < 0) {
return INT_MAX;
}
if (i == 0 && j == 0) {
return grid[i][j];
}
return min(dfs(i, j - 1), dfs(i - 1, j)) + grid[i][j];
};
return dfs(grid.size() - 1, grid[0].size() - 1);
}
};
法二:用记忆化搜索优化
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
vector memo(m, vector<int>(n, -1)); // -1 表示没有计算过
auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i < 0 || j < 0) {
return INT_MAX;
}
if (i == 0 && j == 0) {
return grid[i][j];
}
int& res = memo[i][j]; // 注意这里是引用
if (res != -1) { // 之前计算过
return res;
}
return res = min(dfs(i, j - 1), dfs(i - 1, j)) + grid[i][j];
};
return dfs(m - 1, n - 1);
}
};