Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8c1d32f

Browse files
feat: add solutions to lc problem: No.0120 (doocs#4747)
1 parent 57032bd commit 8c1d32f

File tree

13 files changed

+154
-188
lines changed

13 files changed

+154
-188
lines changed

‎solution/0100-0199/0120.Triangle/README.md‎

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,11 @@ tags:
7373
我们定义 $f[i][j]$ 表示从三角形底部走到位置 $(i, j)$ 的最小路径和。这里的位置 $(i, j)$ 指的是三角形中第 $i$ 行第 $j$ 列(均从 0ドル$ 开始编号)的位置。那么我们有如下的状态转移方程:
7474

7575
$$
76-
f[i][j] = \min(f[i + 1][j], f[i + 1][j + 1]) + triangle[i][j]
76+
f[i][j] = \min(f[i + 1][j], f[i + 1][j + 1]) + \text{triangle}[i][j]
7777
$$
7878

7979
答案即为 $f[0][0]$。
8080

81-
我们注意到,状态 $f[i][j]$ 仅与状态 $f[i + 1][j]$ 和状态 $f[i + 1][j + 1]$ 有关,因此我们可以使用一维数组代替二维数组,将空间复杂度从 $O(n^2)$ 降低至 $O(n)$。
82-
83-
时间复杂度 $O(n^2),ドル空间复杂度 $O(n)$。其中 $n$ 是三角形的行数。
84-
85-
更进一步,我们还可以直接复用 $triangle$ 作为 $f$ 数组,这样就无需再额外创建 $f$ 数组,空间复杂度降低至 $O(1)$。
86-
8781
<!-- tabs:start -->
8882

8983
#### Python3
@@ -105,13 +99,13 @@ class Solution:
10599
class Solution {
106100
public int minimumTotal(List<List<Integer>> triangle) {
107101
int n = triangle.size();
108-
int[] f = new int[n + 1];
102+
int[][] f = new int[n +1][n + 1];
109103
for (int i = n - 1; i >= 0; --i) {
110104
for (int j = 0; j <= i; ++j) {
111-
f[j] = Math.min(f[j], f[j + 1]) + triangle.get(i).get(j);
105+
f[i][j] = Math.min(f[i +1][j], f[i +1][j + 1]) + triangle.get(i).get(j);
112106
}
113107
}
114-
return f[0];
108+
return f[0][0];
115109
}
116110
}
117111
```
@@ -123,14 +117,13 @@ class Solution {
123117
public:
124118
int minimumTotal(vector<vector<int>>& triangle) {
125119
int n = triangle.size();
126-
int f[n + 1];
127-
memset(f, 0, sizeof(f));
128-
for (int i = n - 1; ~i; --i) {
120+
vector<vector<int>> f(n + 1, vector<int>(n + 1, 0));
121+
for (int i = n - 1; i >= 0; --i) {
129122
for (int j = 0; j <= i; ++j) {
130-
f[j] = min(f[j], f[j + 1]) + triangle[i][j];
123+
f[i][j] = min(f[i + 1][j], f[i + 1][j + 1]) + triangle[i][j];
131124
}
132125
}
133-
return f[0];
126+
return f[0][0];
134127
}
135128
};
136129
```
@@ -140,13 +133,16 @@ public:
140133
```go
141134
func minimumTotal(triangle [][]int) int {
142135
n := len(triangle)
143-
f := make([]int, n+1)
136+
f := make([][]int, n+1)
137+
for i := range f {
138+
f[i] = make([]int, n+1)
139+
}
144140
for i := n - 1; i >= 0; i-- {
145141
for j := 0; j <= i; j++ {
146-
f[j] = min(f[j], f[j+1]) + triangle[i][j]
142+
f[i][j] = min(f[i+1][j], f[i+1][j+1]) + triangle[i][j]
147143
}
148144
}
149-
return f[0]
145+
return f[0][0]
150146
}
151147
```
152148

@@ -155,13 +151,13 @@ func minimumTotal(triangle [][]int) int {
155151
```ts
156152
function minimumTotal(triangle: number[][]): number {
157153
const n = triangle.length;
158-
const f: number[] = Array(n + 1).fill(0);
159-
for (let i = n - 1; ~i; --i) {
154+
const f: number[][] = Array.from({ length: n + 1 }, () =>Array(n+1).fill(0));
155+
for (let i = n - 1; i>=0; --i) {
160156
for (let j = 0; j <= i; ++j) {
161-
f[j] = Math.min(f[j], f[j + 1]) + triangle[i][j];
157+
f[i][j] = Math.min(f[i+1][j], f[i+1][j + 1]) + triangle[i][j];
162158
}
163159
}
164-
return f[0];
160+
return f[0][0];
165161
}
166162
```
167163

@@ -171,13 +167,13 @@ function minimumTotal(triangle: number[][]): number {
171167
impl Solution {
172168
pub fn minimum_total(triangle: Vec<Vec<i32>>) -> i32 {
173169
let n = triangle.len();
174-
let mut f = vec![0; n + 1];
170+
let mut f = vec![vec![0; n+1]; n + 1];
175171
for i in (0..n).rev() {
176172
for j in 0..=i {
177-
f[j] = f[j].min(f[j + 1]) + triangle[i][j];
173+
f[i][j] = f[i+1][j].min(f[i+1][j + 1]) + triangle[i][j];
178174
}
179175
}
180-
f[0]
176+
f[0][0]
181177
}
182178
}
183179
```
@@ -188,7 +184,11 @@ impl Solution {
188184

189185
<!-- solution:start -->
190186

191-
### 方法二
187+
### 方法二:动态规划(空间优化)
188+
189+
我们注意到,状态 $f[i][j]$ 仅与状态 $f[i + 1][j]$ 和状态 $f[i + 1][j + 1]$ 有关,因此我们可以使用一维数组代替二维数组,将空间复杂度从 $O(n^2)$ 降低至 $O(n)$。
190+
191+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n)$。其中 $n$ 是三角形的行数。
192192

193193
<!-- tabs:start -->
194194

@@ -210,14 +210,14 @@ class Solution:
210210
```java
211211
class Solution {
212212
public int minimumTotal(List<List<Integer>> triangle) {
213-
for (int i = triangle.size() - 2; i >= 0; --i) {
213+
int n = triangle.size();
214+
int[] f = new int[n + 1];
215+
for (int i = n - 1; i >= 0; --i) {
214216
for (int j = 0; j <= i; ++j) {
215-
int x = triangle.get(i).get(j);
216-
int y = Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1));
217-
triangle.get(i).set(j, x + y);
217+
f[j] = Math.min(f[j], f[j + 1]) + triangle.get(i).get(j);
218218
}
219219
}
220-
return triangle.get(0).get(0);
220+
return f[0];
221221
}
222222
}
223223
```
@@ -228,12 +228,14 @@ class Solution {
228228
class Solution {
229229
public:
230230
int minimumTotal(vector<vector<int>>& triangle) {
231-
for (int i = triangle.size() - 2; ~i; --i) {
231+
int n = triangle.size();
232+
vector<int> f(n + 1, 0);
233+
for (int i = n - 1; i >= 0; --i) {
232234
for (int j = 0; j <= i; ++j) {
233-
triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
235+
f[j] = min(f[j], f[j + 1]) + triangle[i][j];
234236
}
235237
}
236-
return triangle[0][0];
238+
return f[0];
237239
}
238240
};
239241
```
@@ -242,25 +244,29 @@ public:
242244
243245
```go
244246
func minimumTotal(triangle [][]int) int {
245-
for i := len(triangle) - 2; i >= 0; i-- {
247+
n := len(triangle)
248+
f := make([]int, n+1)
249+
for i := n - 1; i >= 0; i-- {
246250
for j := 0; j <= i; j++ {
247-
triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1])
251+
f[j] = min(f[j], f[j+1]) + triangle[i][j]
248252
}
249253
}
250-
return triangle[0][0]
254+
return f[0]
251255
}
252256
```
253257

254258
#### TypeScript
255259

256260
```ts
257261
function minimumTotal(triangle: number[][]): number {
258-
for (let i = triangle.length - 2; ~i; --i) {
262+
const n = triangle.length;
263+
const f: number[] = Array(n + 1).fill(0);
264+
for (let i = n - 1; i >= 0; --i) {
259265
for (let j = 0; j <= i; ++j) {
260-
triangle[i][j] += Math.min(triangle[i+1][j], triangle[i + 1][j + 1]);
266+
f[j] = Math.min(f[j], f[j + 1]) + triangle[i][j];
261267
}
262268
}
263-
return triangle[0][0];
269+
return f[0];
264270
}
265271
```
266272

@@ -269,13 +275,14 @@ function minimumTotal(triangle: number[][]): number {
269275
```rust
270276
impl Solution {
271277
pub fn minimum_total(triangle: Vec<Vec<i32>>) -> i32 {
272-
let mut triangle = triangle;
273-
for i in (0..triangle.len() - 1).rev() {
278+
let n = triangle.len();
279+
let mut f = vec![0; n + 1];
280+
for i in (0..n).rev() {
274281
for j in 0..=i {
275-
triangle[i][j] +=triangle[i+1][j].min(triangle[i + 1][j + 1]);
282+
f[j] =f[j].min(f[j + 1]) + triangle[i][j];
276283
}
277284
}
278-
triangle[0][0]
285+
f[0]
279286
}
280287
}
281288
```
@@ -284,28 +291,4 @@ impl Solution {
284291

285292
<!-- solution:end -->
286293

287-
<!-- solution:start -->
288-
289-
### 方法三
290-
291-
<!-- tabs:start -->
292-
293-
#### Python3
294-
295-
```python
296-
class Solution:
297-
def minimumTotal(self, triangle: List[List[int]]) -> int:
298-
n = len(triangle)
299-
for i in range(n - 2, -1, -1):
300-
for j in range(i + 1):
301-
triangle[i][j] = (
302-
min(triangle[i + 1][j], triangle[i + 1][j + 1]) + triangle[i][j]
303-
)
304-
return triangle[0][0]
305-
```
306-
307-
<!-- tabs:end -->
308-
309-
<!-- solution:end -->
310-
311294
<!-- problem:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /