Skip to content

Commit 4ee6a2c

Browse files
committed
64 Minimum Path Sum
1 parent f3a5e5e commit 4ee6a2c

File tree

4 files changed

+135
-0
lines changed

4 files changed

+135
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
+ [50 Pow(x, n)(二分,浮点数比较,INT\_MIN绝对值)](algorithms/Pow)
2525
+ [58 Length of Last Word](algorithms/LengthofLastWord)
2626
+ [60 Permutation Sequence(康托展开)](algorithms/PermutationSequence)
27+
+ [64 Minimum Path Sum(DP,空间压缩)](algorithms/MinimumPathSum)
2728
+ [65 Valid Number(细节题,状态机)](algorithms/ValidNumber)
2829
+ [67 Add Binary](algorithms/AddBinary)
2930
+ [72 Edit Distance(DP)](algorithms/EditDistance)

algorithms/MinimumPathSum/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Minimum Path Sum
2+
3+
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.
4+
5+
**Note: You can only move either down or right at any point in time.**
6+
7+
## Solution
8+
9+
最开始想到用BFS,这思维!
10+
11+
显然这是最最经典直接的DP问题。
12+
13+
`dp[i][j]`表示`a[0][0]``a[i][j]`的最小路径, 则显然有动态方程`dp[i][j] = MIN(dp[i - 1][j], dp[i][j - 1])`,
14+
```cpp
15+
int minPathSum(vector<vector<int>> &grid) {
16+
if (grid.size() < 1)
17+
return 0;
18+
int n = grid.size();
19+
int m = grid[0].size();
20+
vector<vector<int>> dp(n, vector<int>(m, 0));
21+
dp[0][0] = grid[0][0];
22+
for (int i = 1; i < n; ++i)
23+
dp[i][0] = dp[i - 1][0] + grid[i][0];
24+
for (int j = 1; j < m; ++j)
25+
dp[0][j] = dp[0][j - 1] + grid[0][j];
26+
for (int i = 1; i < n; ++i)
27+
for (int j = 1; j < m; ++j)
28+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
29+
return dp[n - 1][m - 1];
30+
}
31+
```
32+
33+
时间和空间复杂度都是O(nm)。时间复杂度没有什么优化方案,当空间可以采用压缩的方法,显然`dp[i][j]`只依赖于左边和上边一个值,即`dp[i - 1][j]`和`dp[i][j - 1]`,
34+
而与前面的值无关。所以处理第i行j列时,与i-1行的该j列有关,以及i行j-1列有关,我们只需要声明dp[i], dp表示第i行j列的值,旧值dp[i]相当于`dp[i][j - 1]`,
35+
`dp[i - 1]`相当于`dp[i - 1][j]`,于是`dp[i] = MIN (dp[i], dp[i - 1]`
36+
```cpp
37+
int minPathSum(vector<vector<int>> &grid) {
38+
if (grid.size() < 1)
39+
return 0;
40+
int n = grid.size();
41+
int m = grid[0].size();
42+
vector<int> dp(n, 0);
43+
dp[0] = grid[0][0];
44+
for (int i = 1; i < n; ++i)
45+
dp[i] = dp[i - 1] + grid[i][0];
46+
for (int i = 1; i < n; ++i)
47+
for (int j = 1; j < n; ++j) {
48+
dp[j] = min(dp[j], dp[j - 1]) + grid[i][j];
49+
}
50+
return dp[n - 1];
51+
}
52+
```

algorithms/MinimumPathSum/in.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
3 3
2+
1 2 0
3+
0 5 1
4+
3 6 0
5+
19 10
6+
1 7 4 3 2 2 2 9 2 6
7+
3 6 6 1 0 5 9 6 3 8
8+
1 5 4 5 3 8 7 2 5 6
9+
5 7 6 9 0 8 1 4 7 5
10+
0 2 1 9 5 3 6 5 9 9
11+
5 3 6 1 8 9 0 7 4 7
12+
6 9 4 2 0 6 0 3 2 9
13+
8 3 3 1 2 9 5 8 6 6
14+
9 1 9 5 4 7 6 4 5 0
15+
4 1 1 8 5 1 7 5 4 9
16+
6 4 4 9 8 8 8 5 8 4
17+
1 7 7 3 2 4 0 9 8 7
18+
1 4 0 3 5 5 4 2 2 1
19+
3 0 5 8 0 3 6 0 0 5
20+
7 2 4 6 5 7 0 7 8 1
21+
7 9 5 7 4 0 5 1 4 9
22+
2 8 0 9 8 2 5 6 2 5
23+
3 9 9 8 6 4 7 8 4 5
24+
9 1 6 5 0 3 5 5 4 0

algorithms/MinimumPathSum/solve.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <vector>
4+
#include <algorithm>
5+
#include <iostream>
6+
using namespace std;
7+
class Solution {
8+
public:
9+
int minPathSum(vector<vector<int>> &grid) {
10+
return minPathSum1(grid);
11+
}
12+
private:
13+
int minPathSum1(vector<vector<int>> &grid) {
14+
if (grid.size() < 1)
15+
return 0;
16+
int n = grid.size();
17+
int m = grid[0].size();
18+
vector<vector<int>> dp(n, vector<int>(m, 0));
19+
dp[0][0] = grid[0][0];
20+
for (int i = 1; i < n; ++i)
21+
dp[i][0] = dp[i - 1][0] + grid[i][0];
22+
for (int j = 1; j < m; ++j)
23+
dp[0][j] = dp[0][j - 1] + grid[0][j];
24+
for (int i = 1; i < n; ++i)
25+
for (int j = 1; j < m; ++j)
26+
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
27+
return dp[n - 1][m - 1];
28+
}
29+
int minPathSum2(vector<vector<int>> &grid) {
30+
if (grid.size() < 1)
31+
return 0;
32+
int n = grid.size();
33+
int m = grid[0].size();
34+
vector<int> dp(n, 0);
35+
dp[0] = grid[0][0];
36+
for (int i = 1; i < n; ++i)
37+
dp[i] = dp[i - 1] + grid[i][0];
38+
for (int i = 1; i < n; ++i)
39+
for (int j = 1; j < n; ++j) {
40+
dp[j] = min(dp[j], dp[j - 1]) + grid[i][j];
41+
}
42+
return dp[n - 1];
43+
}
44+
};
45+
int main(int argc, char **argv)
46+
{
47+
Solution solution;
48+
int n, m;
49+
while (scanf("%d%d", &n, &m) != EOF) {
50+
vector<vector<int>> v(n, vector<int>(m, 0));
51+
for (int i = 0; i < n; ++i)
52+
for (int j = 0; j < m; ++j) {
53+
cin >> v[i][j];
54+
}
55+
cout << solution.minPathSum(v) << endl;
56+
}
57+
return 0;
58+
}

0 commit comments

Comments
 (0)