55
55
56
56
<!-- 这里可写通用的实现逻辑 -->
57
57
58
- 动态规划。自底向上。
58
+ ** 方法一:动态规划**
59
+
60
+ 我们定义 $f[ i] [ j ] $ 表示从三角形底部走到位置 $(i, j)$ 的最小路径和。这里的位置 $(i, j)$ 指的是三角形中第 $i$ 行第 $j$ 列(均从 $0$ 开始编号)的位置。那么我们有如下的状态转移方程:
61
+
62
+ $$
63
+ f[i][j] = \min(f[i + 1][j], f[i + 1][j + 1]) + triangle[i][j]
64
+ $$
65
+
66
+ 答案即为 $f[ 0] [ 0 ] $。
67
+
68
+ 我们注意到,状态 $f[ i] [ j ] $ 仅与状态 $f[ i + 1] [ j ] $ 和状态 $f[ i + 1] [ j + 1 ] $ 有关,因此我们可以使用一维数组代替二维数组,将空间复杂度从 $O(n^2)$ 降低至 $O(n)$。
69
+
70
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是三角形的行数。
71
+
72
+ 更进一步,我们还可以直接复用 $triangle$ 作为 $f$ 数组,这样就无需再额外创建 $f$ 数组,空间复杂度降低至 $O(1)$。
59
73
60
74
<!-- tabs:start -->
61
75
67
81
class Solution :
68
82
def minimumTotal (self , triangle : List[List[int ]]) -> int :
69
83
n = len (triangle)
70
- dp = [[0 ] * (n + 1 ) for _ in range (n + 1 )]
84
+ f = [[0 ] * (n + 1 ) for _ in range (n + 1 )]
71
85
for i in range (n - 1 , - 1 , - 1 ):
72
86
for j in range (i + 1 ):
73
- dp [i][j] = min (dp [i + 1 ][j], dp [i + 1 ][j + 1 ]) + triangle[i][j]
74
- return dp [0 ][0 ]
87
+ f [i][j] = min (f [i + 1 ][j], f [i + 1 ][j + 1 ]) + triangle[i][j]
88
+ return f [0 ][0 ]
75
89
```
76
90
77
- 空间优化:
78
-
79
91
``` python
80
92
class Solution :
81
93
def minimumTotal (self , triangle : List[List[int ]]) -> int :
82
94
n = len (triangle)
83
- dp = [0 ] * (n + 1 )
95
+ f = [0 ] * (n + 1 )
84
96
for i in range (n - 1 , - 1 , - 1 ):
85
97
for j in range (i + 1 ):
86
- dp[j] = min (dp[j], dp[j + 1 ]) + triangle[i][j]
87
- return dp[0 ]
98
+ f[j] = min (f[j], f[j + 1 ]) + triangle[i][j]
99
+ return f[0 ]
100
+ ```
101
+
102
+ ``` python
103
+ class Solution :
104
+ def minimumTotal (self , triangle : List[List[int ]]) -> int :
105
+ n = len (triangle)
106
+ for i in range (n - 2 , - 1 , - 1 ):
107
+ for j in range (i + 1 ):
108
+ triangle[i][j] = (
109
+ min (triangle[i + 1 ][j], triangle[i + 1 ][j + 1 ]) + triangle[i][j]
110
+ )
111
+ return triangle[0 ][0 ]
88
112
```
89
113
90
114
### ** Java**
@@ -95,13 +119,28 @@ class Solution:
95
119
class Solution {
96
120
public int minimumTotal (List<List<Integer > > triangle ) {
97
121
int n = triangle. size();
98
- int [] dp = new int [n + 1 ];
122
+ int [] f = new int [n + 1 ];
99
123
for (int i = n - 1 ; i >= 0 ; -- i) {
100
124
for (int j = 0 ; j <= i; ++ j) {
101
- dp [j] = Math . min(dp [j], dp [j + 1 ]) + triangle. get(i). get(j);
125
+ f [j] = Math . min(f [j], f [j + 1 ]) + triangle. get(i). get(j);
102
126
}
103
127
}
104
- return dp[0 ];
128
+ return f[0 ];
129
+ }
130
+ }
131
+ ```
132
+
133
+ ``` java
134
+ class Solution {
135
+ public int minimumTotal (List<List<Integer > > triangle ) {
136
+ for (int i = triangle. size() - 2 ; i >= 0 ; -- i) {
137
+ for (int j = 0 ; j <= i; ++ j) {
138
+ int x = triangle. get(i). get(j);
139
+ int y = Math . min(triangle. get(i + 1 ). get(j), triangle. get(i + 1 ). get(j + 1 ));
140
+ triangle. get(i). set(j, x + y);
141
+ }
142
+ }
143
+ return triangle. get(0 ). get(0 );
105
144
}
106
145
}
107
146
```
@@ -113,11 +152,28 @@ class Solution {
113
152
public:
114
153
int minimumTotal(vector<vector<int >>& triangle) {
115
154
int n = triangle.size();
116
- vector<int > dp(n + 1);
117
- for (int i = n - 1; i >= 0; --i)
118
- for (int j = 0; j <= i; ++j)
119
- dp[ j] = min(dp[ j] , dp[ j + 1] ) + triangle[ i] [ j ] ;
120
- return dp[ 0] ;
155
+ int f[ n + 1] ;
156
+ memset(f, 0, sizeof(f));
157
+ for (int i = n - 1; ~ i; --i) {
158
+ for (int j = 0; j <= i; ++j) {
159
+ f[ j] = min(f[ j] , f[ j + 1] ) + triangle[ i] [ j ] ;
160
+ }
161
+ }
162
+ return f[ 0] ;
163
+ }
164
+ };
165
+ ```
166
+
167
+ ```cpp
168
+ class Solution {
169
+ public:
170
+ int minimumTotal(vector<vector<int>>& triangle) {
171
+ for (int i = triangle.size() - 2; ~i; --i) {
172
+ for (int j = 0; j <= i; ++j) {
173
+ triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
174
+ }
175
+ }
176
+ return triangle[0][0];
121
177
}
122
178
};
123
179
```
@@ -127,13 +183,24 @@ public:
127
183
``` go
128
184
func minimumTotal (triangle [][]int ) int {
129
185
n := len (triangle)
130
- dp := make([]int, n+1)
186
+ f := make ([]int , n+1 )
131
187
for i := n - 1 ; i >= 0 ; i-- {
132
188
for j := 0 ; j <= i; j++ {
133
- dp[j] = min(dp[j], dp[j+1]) + triangle[i][j]
189
+ f[j] = min (f[j], f[j+1 ]) + triangle[i][j]
190
+ }
191
+ }
192
+ return f[0 ]
193
+ }
194
+ ```
195
+
196
+ ``` go
197
+ func minimumTotal (triangle [][]int ) int {
198
+ for i := len (triangle) - 2 ; i >= 0 ; i-- {
199
+ for j := 0 ; j <= i; j++ {
200
+ triangle[i][j] += min (triangle[i+1 ][j], triangle[i+1 ][j+1 ])
134
201
}
135
202
}
136
- return dp [0]
203
+ return triangle[ 0 ] [0 ]
137
204
}
138
205
```
139
206
@@ -142,8 +209,20 @@ func minimumTotal(triangle [][]int) int {
142
209
``` ts
143
210
function minimumTotal(triangle : number [][]): number {
144
211
const n = triangle .length ;
145
- for (let i = n - 2 ; i >= 0 ; i -- ) {
146
- for (let j = 0 ; j < i + 1 ; j ++ ) {
212
+ const f: number [] = Array (n + 1 ).fill (0 );
213
+ for (let i = n - 1 ; ~ i ; -- i ) {
214
+ for (let j = 0 ; j <= i ; ++ j ) {
215
+ f [j ] = Math .min (f [j ], f [j + 1 ]) + triangle [i ][j ];
216
+ }
217
+ }
218
+ return f [0 ];
219
+ }
220
+ ```
221
+
222
+ ``` ts
223
+ function minimumTotal(triangle : number [][]): number {
224
+ for (let i = triangle .length - 2 ; ~ i ; -- i ) {
225
+ for (let j = 0 ; j <= i ; ++ j ) {
147
226
triangle [i ][j ] += Math .min (triangle [i + 1 ][j ], triangle [i + 1 ][j + 1 ]);
148
227
}
149
228
}
@@ -155,10 +234,25 @@ function minimumTotal(triangle: number[][]): number {
155
234
156
235
``` rust
157
236
impl Solution {
158
- pub fn minimum_total (mut triangle : Vec <Vec <i32 >>) -> i32 {
237
+ pub fn minimum_total (triangle : Vec <Vec <i32 >>) -> i32 {
159
238
let n = triangle . len ();
160
- for i in (0 .. n - 1 ). rev () {
161
- for j in 0 .. i + 1 {
239
+ let mut f = vec! [0 ; n + 1 ];
240
+ for i in (0 .. n ). rev () {
241
+ for j in 0 ..= i {
242
+ f [j ] = f [j ]. min (f [j + 1 ]) + triangle [i ][j ];
243
+ }
244
+ }
245
+ f [0 ]
246
+ }
247
+ }
248
+ ```
249
+
250
+ ``` rust
251
+ impl Solution {
252
+ pub fn minimum_total (triangle : Vec <Vec <i32 >>) -> i32 {
253
+ let mut triangle = triangle ;
254
+ for i in (0 .. triangle . len () - 1 ). rev () {
255
+ for j in 0 ..= i {
162
256
triangle [i ][j ] += triangle [i + 1 ][j ]. min (triangle [i + 1 ][j + 1 ]);
163
257
}
164
258
}
0 commit comments