Skip to content

Commit 04082e7

Browse files
committed
#64 最小路径和,dp版本,其中设计最优解选取, 分解子问题的时候,将每一步中涉及到的最优选择找出共性,归纳
1 parent db8d619 commit 04082e7

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package dynamic_programming;
2+
3+
/**
4+
* @author alis
5+
* @date 2019/11/17 10:54 PM
6+
* @description
7+
*/
8+
public class LC_64_MinPathSum {
9+
/**
10+
* 解法:暴力遍历所有路径的和的解法就不实现了,就算实现出来也是超时;
11+
* 直接使用DP来实现
12+
* 最优dp方程:dp(i,j)=grid(i,j)+min(dp(i+1,j),dp(i,j+1))
13+
* dp三部曲:
14+
* 1. 子问题
15+
* 2. 状态定义
16+
* 3. DP方程
17+
*
18+
* @param grid 网格
19+
* @return
20+
* @date 2019/11/17 10:55 PM
21+
*/
22+
public int minPathSum(int[][] grid) {
23+
int rows = grid.length;
24+
int column = grid[0].length;
25+
if (rows == 0 && column == 0) return 0;
26+
int[][] dp = new int[rows][column];
27+
for (int i = rows - 1; i >= 0; i--) {
28+
for (int j = column - 1; j >= 0; j--) {
29+
30+
if (i == rows - 1 && j != column - 1)
31+
// 最后一行排除最后一列的节点([rows-1][column-1])
32+
// 最后一行的路径数计算只会从上一步加过来
33+
dp[i][j] = grid[i][j] + dp[i][j + 1];
34+
else if (j == column - 1 && i != rows - 1)
35+
// 最后一列排除最后一行的节点[rows-1][column-1]
36+
// 当前节点计数需要从上一个节点反推
37+
dp[i][j] = grid[i][j] + dp[i + 1][j];
38+
else if (j != column - 1 && i != rows - 1)
39+
dp[i][j] = grid[i][j] + Math.min(dp[i + 1][j], dp[i][j + 1]);
40+
else
41+
dp[i][j] = grid[i][j];
42+
}
43+
}
44+
return dp[0][0];
45+
}
46+
47+
/**
48+
* 最小路径和
49+
* dp版本思路
50+
* 1. 第(i,j)个格子,是从(i-1,j)或者是(i,j-1)走过来,而选择哪条路径,则按照选择路径数最少的那个格子过来,并且计算当前格子的路径和的时候,需要加上自身
51+
* 2. 状态转移方程:f(i,j) = grid(i,j) + min(f(i-1,j), f(i,j-1))
52+
* 3. 递推初始值,将(i,0)和(0,j)行/列填满,再进行递推过程
53+
*/
54+
public int minPathSum_DP_Review(int[][] grid) {
55+
int rows = grid.length;
56+
int column = grid[0].length;
57+
int[][] dp = new int[rows][column];
58+
dp[0][0] = grid[0][0];
59+
for (int i = 1; i < rows; i++) {
60+
dp[i][0] = grid[i][0] + dp[i - 1][0];
61+
}
62+
for (int j = 1; j < column; j++) {
63+
dp[0][j] = grid[0][j] + dp[0][j - 1];
64+
}
65+
for (int i = 1; i < rows; i++) {
66+
for (int j = 1; j < column; j++) {
67+
dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]);
68+
}
69+
}
70+
return dp[rows - 1][column - 1];
71+
}
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package dynamic_programming;
2+
3+
import org.junit.Test;
4+
5+
import static org.hamcrest.core.Is.is;
6+
import static org.junit.Assert.assertThat;
7+
8+
/**
9+
* @author alis
10+
* @date 2019/11/17 10:52 PM
11+
* @description
12+
*/
13+
public class LC_64_MinPathSumTest {
14+
15+
private LC_64_MinPathSum minPathSumDomain = new LC_64_MinPathSum();
16+
17+
@Test
18+
public void testMinPathSumDomain() {
19+
assertThat(minPathSumDomain.minPathSum(new int[][]{
20+
{1, 3, 1},
21+
{1, 5, 1},
22+
{4, 2, 1}
23+
}), is(7));
24+
}
25+
26+
@Test
27+
public void testMinPathSumDP_Review() {
28+
assertThat(minPathSumDomain.minPathSum_DP_Review(new int[][]{
29+
{1, 3, 1},
30+
{1, 5, 1},
31+
{4, 2, 1}
32+
}), is(7));
33+
}
34+
}

0 commit comments

Comments
 (0)