第一种:动态规划
思路
在过去,有这样一个词,那就是遇难则反,从起点推导出最小路径和是困难的,那我们就从终点去推导。
解题过程
我们都知道一个方块,只能向右或向下。在初始化dp之后,我们会有这样一条关系式:
d p [ i ] [ j ] = { g r i d [ m − 1 ] [ n − 1 ] if i = = m − 1 a n d j = = n − 1 m i n ( d p [ i + 1 ] [ j ] + g r i d [ i ] [ j ] , d p [ i ] [ j + 1 ] + g r i d [ i ] [ j ] ) if i + 1 < m a n d j + 1 < n m i n ( d p [ i + 1 ] [ j ] + g r i d [ i ] [ j ] , d p [ i ] [ j ] ) if i + 1 < m m i n ( d p [ i ] [ j ] , d p [ i ] [ j + 1 ] + g r i d [ i ] [ j ] ) if j + 1 < n dp[i][j] = \left\{\begin{matrix} grid[m-1][n-1]&\text{if } i == m-1 \ and \ j == n-1 \\ min(dp[i+1][j] + grid[i][j], dp[i][j+1] + grid[i][j])&\text{if } i+1 < m \ and \ j+1 < n \\ min(dp[i+1][j] + grid[i][j], dp[i][j])&\text{if } i+1 < m \\ min(dp[i][j], dp[i][j+1] + grid[i][j])&\text{if } \ j+1 < n \end{matrix} \right. dp[i][j]=⎩ ⎨ ⎧grid[m−1][n−1]min(dp[i+1][j]+grid[i][j],dp[i][j+1]+grid[i][j])min(dp[i+1][j]+grid[i][j],dp[i][j])min(dp[i][j],dp[i][j+1]+grid[i][j])if i==m−1 and j==n−1if i+1<m and j+1<nif i+1<mif j+1<n
复杂度
时间复杂度: O ( N ⋅ M ) O(N \cdot M) O(N⋅M)
空间复杂度: O ( N ⋅ M ) O(N \cdot M) O(N⋅M)
Code
class Solution {
public:
int minPathSum(vector< vector<int> > & grid) {
vector<vector<int>> dp;
int m = grid.size(), n = grid[0].size();
for(int i = 1; i <= m; ++i) {
vector<int> t (n, INT_MAX);
dp.push_back(t);
}
dp[m-1][n-1] = grid[m-1][n-1];
for(int i = m-1; i >= 0; --i) {
for(int j = n-1; j >= 0; --j) {
if(i == m-1 && j == n-1) continue;
if(i+1 < m && j+1 < n) {
dp[i][j] = min(dp[i+1][j] + grid[i][j], dp[i][j+1] + grid[i][j]);
} else {
if(i+1 < m) {
dp[i][j] = min(dp[i+1][j] + grid[i][j], dp[i][j]);
}
if(j+1 < n) {
dp[i][j] = min(dp[i][j+1] + grid[i][j], dp[i][j]);
}
}
}
}
return dp[0][0];
}
};
第二种:BFS
思路
在过去,有这样一个词,那就是遇难则反,从起点推导出最小路径和是困难的,那我们就从终点去推导。
解题过程
这个其实就是利用优化过后的bfs去解决的
复杂度
时间复杂度: O ( M n ) O(Mn) O(Mn)
空间复杂度: O ( n ) O(n) O(n)
Code
class Solution {
public:
int minPathSum(vector< vector<int> > & grid) {
vector<vector<int>> dp;
int m = grid.size(), n = grid[0].size();
for(int i = 1; i <= m; ++i) {
vector<int> t (n, INT_MAX);
dp.push_back(t);
}
int xs[3] = {-1, 0};
int ys[3] = {0, -1};
int MINCount = INT_MAX;
int cury = m-1, curx = n-1;
dp[cury][curx] = grid[cury][curx];
queue<pair<int, int>> Q;
Q.push({curx, cury});
while(!Q.empty()) {
pair<int, int> top = Q.front();
Q.pop();
for(int i = 0; i < 2; ++i) {
int tx = top.first + xs[i], ty = top.second + ys[i];
if(tx < 0 || ty < 0) continue;
if(i == 0) {
if(dp[top.second][top.first] + grid[ty][tx] < dp[ty][tx]) {
dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
Q.push({tx, ty});
}
} else {
if(top.second+ys[0] >= 0 && top.first+xs[0] >= 0 && dp[top.second][top.first] + grid[ty][tx] < dp[top.second+ys[0]][top.first+xs[0]]) {
dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
Q.push({tx, ty});
} else if(dp[top.second][top.first] + grid[ty][tx] < dp[ty][tx]) {
dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
Q.push({tx, ty});
}
}
}
}
return dp[0][0];
}
};