问题描述
思路
思路就是动态规划,如果采用递归会超时,其最主要的是写出状态转移方程。主要就是dp求解的过程中的边界值的细节要做好。
f
u
n
(
d
e
p
t
h
,
i
)
=
{
m
i
n
(
f
u
n
(
d
e
p
t
h
−
1
,
i
)
,
f
u
n
(
d
e
p
t
h
,
i
−
1
)
)
+
t
r
i
a
n
g
l
e
[
d
e
p
t
h
]
[
i
]
d
e
p
t
h
>
1
,
0
<
=
i
<
t
r
i
a
n
g
l
e
[
d
e
p
t
h
−
1
]
.
l
e
n
g
t
h
f
u
n
(
d
e
p
t
h
−
1
,
i
)
+
t
r
i
a
n
g
l
e
[
d
e
p
t
h
]
[
i
]
d
e
p
t
h
>
1
,
i
−
1
<
0
f
u
n
(
d
e
p
t
h
−
1
,
i
−
1
)
+
t
r
i
a
n
g
l
e
[
d
e
p
t
h
]
[
i
]
d
e
p
t
h
>
1
,
i
>
=
t
r
i
a
n
g
l
e
[
d
e
p
t
h
−
1
]
.
l
e
n
g
t
h
t
r
i
a
n
g
l
e
[
0
]
[
0
]
d
e
p
t
h
=
1
fun(depth, i)=\begin{cases} min(fun(depth-1, i), fun(depth, i-1)) + triangle[depth][i] & depth > 1, 0 <= i < triangle[depth-1].length \\ fun(depth-1, i) + triangle[depth][i] & depth > 1, i-1 < 0 \\ fun(depth-1, i-1) + triangle[depth][i] & depth > 1, i >= triangle[depth-1].length \\ triangle[0][0] & depth = 1 \end{cases}
fun(depth,i)=⎩⎪⎪⎪⎨⎪⎪⎪⎧min(fun(depth−1,i),fun(depth,i−1))+triangle[depth][i]fun(depth−1,i)+triangle[depth][i]fun(depth−1,i−1)+triangle[depth][i]triangle[0][0]depth>1,0<=i<triangle[depth−1].lengthdepth>1,i−1<0depth>1,i>=triangle[depth−1].lengthdepth=1
我是从递归改到dp的。
Code
超时的递归
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size() == 0) return 0;
return dp(triangle, 0, 0);
}
public int dp(List<List<Integer>> triangle, int x, int depth) {
if (depth >= triangle.size()) return 0;
if (x >= triangle.get(depth).size()) return 0;
return Math.min(dp(triangle, x, depth+1), dp(triangle, x+1, depth+1)) + triangle.get(depth).get(x);
}
}
改良的DP
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size() == 0) return 0;
int[][] dp = new int[triangle.size()][triangle.get(triangle.size()-1).size()];
dp[0][0] =triangle.get(0).get(0);
for (int i = 1; i < triangle.size(); i++) {
int len = triangle.get(i).size();
for (int j = 0; j < len; j++) {
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE;
if (j - 1 >= 0) a = dp[i-1][j-1];
if (j < len -1) b = dp[i-1][j];
dp[i][j] = Math.min(a, b) + triangle.get(i).get(j);
}
}
int[] ints = dp[dp.length - 1];
int n = ints[0];
for (int i = 1; i < ints.length; i++) if (n > ints[i]) n = ints[i];
return n;
}
}