Skip to content

Commit 024f357

Browse files
authored
Update README_EN.md
1 parent f32bb13 commit 024f357

File tree

1 file changed

+199
-81
lines changed
  • solution/0700-0799/0746.Min Cost Climbing Stairs

1 file changed

+199
-81
lines changed

solution/0700-0799/0746.Min Cost Climbing Stairs/README_EN.md

Lines changed: 199 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,189 @@ The total cost is 6.
6363

6464
<!-- solution:start -->
6565

66-
### Solution 1: Dynamic Programming
66+
### Solution 1: Memoization Search
6767

68-
We define $f[i]$ as the minimum cost required to reach the $i$th step, initially $f[0] = f[1] = 0$. The answer is $f[n]$.
68+
We design a function $\textit{dfs}(i)$, which represents the minimum cost required to climb the stairs starting from the $i$-th step. Therefore, the answer is $\min(\textit{dfs}(0), \textit{dfs}(1))$.
6969

70-
When $i \ge 2$, we can directly reach the $i$th step from the $(i - 1)$th step using $1$ step, or reach the $i$th step from the $(i - 2)$th step using $2$ steps. Therefore, we have the state transition equation:
70+
The execution process of the function $\textit{dfs}(i)$ is as follows:
71+
72+
- If $i \ge \textit{len(cost)}$, it means the current position has exceeded the top of the stairs, and there is no need to climb further, so return $0$;
73+
- Otherwise, we can choose to climb $1$ step with a cost of $\textit{cost}[i]$, then recursively call $\textit{dfs}(i + 1)$; or we can choose to climb $2$ steps with a cost of $\textit{cost}[i]$, then recursively call $\textit{dfs}(i + 2)$;
74+
- Return the minimum cost between these two options.
75+
76+
To avoid repeated calculations, we use memoization search, saving the results that have already been calculated in an array or hash table.
77+
78+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{cost}$.
79+
80+
<!-- tabs:start -->
81+
82+
#### Python3
83+
84+
```python
85+
class Solution:
86+
def minCostClimbingStairs(self, cost: List[int]) -> int:
87+
@cache
88+
def dfs(i: int) -> int:
89+
if i >= len(cost):
90+
return 0
91+
return cost[i] + min(dfs(i + 1), dfs(i + 2))
92+
93+
return min(dfs(0), dfs(1))
94+
```
95+
96+
#### Java
97+
98+
```java
99+
class Solution {
100+
private Integer[] f;
101+
private int[] cost;
102+
103+
public int minCostClimbingStairs(int[] cost) {
104+
this.cost = cost;
105+
f = new Integer[cost.length];
106+
return Math.min(dfs(0), dfs(1));
107+
}
108+
109+
private int dfs(int i) {
110+
if (i >= cost.length) {
111+
return 0;
112+
}
113+
if (f[i] == null) {
114+
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
115+
}
116+
return f[i];
117+
}
118+
}
119+
```
120+
121+
#### C++
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
int minCostClimbingStairs(vector<int>& cost) {
127+
int n = cost.size();
128+
int f[n];
129+
memset(f, -1, sizeof(f));
130+
auto dfs = [&](auto&& dfs, int i) -> int {
131+
if (i >= n) {
132+
return 0;
133+
}
134+
if (f[i] < 0) {
135+
f[i] = cost[i] + min(dfs(dfs, i + 1), dfs(dfs, i + 2));
136+
}
137+
return f[i];
138+
};
139+
return min(dfs(dfs, 0), dfs(dfs, 1));
140+
}
141+
};
142+
```
143+
144+
#### Go
145+
146+
```go
147+
func minCostClimbingStairs(cost []int) int {
148+
n := len(cost)
149+
f := make([]int, n)
150+
for i := range f {
151+
f[i] = -1
152+
}
153+
var dfs func(int) int
154+
dfs = func(i int) int {
155+
if i >= n {
156+
return 0
157+
}
158+
if f[i] < 0 {
159+
f[i] = cost[i] + min(dfs(i+1), dfs(i+2))
160+
}
161+
return f[i]
162+
}
163+
return min(dfs(0), dfs(1))
164+
}
165+
```
166+
167+
#### TypeScript
168+
169+
```ts
170+
function minCostClimbingStairs(cost: number[]): number {
171+
const n = cost.length;
172+
const f: number[] = Array(n).fill(-1);
173+
const dfs = (i: number): number => {
174+
if (i >= n) {
175+
return 0;
176+
}
177+
if (f[i] < 0) {
178+
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
179+
}
180+
return f[i];
181+
};
182+
return Math.min(dfs(0), dfs(1));
183+
}
184+
```
185+
186+
#### Rust
187+
188+
```rust
189+
impl Solution {
190+
pub fn min_cost_climbing_stairs(cost: Vec<i32>) -> i32 {
191+
let n = cost.len();
192+
let mut f = vec![-1; n];
193+
194+
fn dfs(i: usize, cost: &Vec<i32>, f: &mut Vec<i32>, n: usize) -> i32 {
195+
if i >= n {
196+
return 0;
197+
}
198+
if f[i] < 0 {
199+
let next1 = dfs(i + 1, cost, f, n);
200+
let next2 = dfs(i + 2, cost, f, n);
201+
f[i] = cost[i] + next1.min(next2);
202+
}
203+
f[i]
204+
}
205+
206+
dfs(0, &cost, &mut f, n).min(dfs(1, &cost, &mut f, n))
207+
}
208+
}
209+
```
210+
211+
#### JavaScript
212+
213+
```js
214+
function minCostClimbingStairs(cost) {
215+
const n = cost.length;
216+
const f = Array(n).fill(-1);
217+
const dfs = i => {
218+
if (i >= n) {
219+
return 0;
220+
}
221+
if (f[i] < 0) {
222+
f[i] = cost[i] + Math.min(dfs(i + 1), dfs(i + 2));
223+
}
224+
return f[i];
225+
};
226+
return Math.min(dfs(0), dfs(1));
227+
}
228+
```
229+
230+
<!-- tab:end -->
231+
232+
<!-- solution:end -->
233+
234+
<!-- solution:start -->
235+
236+
### Solution 2: Dynamic Programming
237+
238+
We define $f[i]$ as the minimum cost needed to reach the $i$-th stair. Initially, $f[0] = f[1] = 0$, and the answer is $f[n]$.
239+
240+
When $i \ge 2$, we can reach the $i$-th stair directly from the $(i - 1)$-th stair with one step, or from the $(i - 2)$-th stair with two steps. Therefore, we have the state transition equation:
71241

72242
$$
73-
f[i] = \min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2])
243+
f[i] = \min(f[i - 1] + \textit{cost}[i - 1], f[i - 2] + \textit{cost}[i - 2])
74244
$$
75245

76246
The final answer is $f[n]$.
77247

78-
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the `cost` array.
79-
80-
We notice that $f[i]$ in the state transition equation is only related to $f[i - 1]$ and $f[i - 2]$. Therefore, we can use two variables $f$ and $g$ to alternately record the values of $f[i - 2]$ and $f[i - 1]$, which optimizes the space complexity to $O(1)$.
248+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{cost}$.
81249

82250
<!-- tabs:start -->
83251

@@ -150,19 +318,6 @@ function minCostClimbingStairs(cost: number[]): number {
150318
}
151319
```
152320

153-
#### JavaScript
154-
155-
```js
156-
function minCostClimbingStairs(cost) {
157-
const n = cost.length;
158-
const f = Array(n + 1).fill(0);
159-
for (let i = 2; i <= n; ++i) {
160-
f[i] = Math.min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]);
161-
}
162-
return f[n];
163-
}
164-
```
165-
166321
#### Rust
167322

168323
```rust
@@ -178,13 +333,28 @@ impl Solution {
178333
}
179334
```
180335

336+
#### JavaScript
337+
338+
```js
339+
function minCostClimbingStairs(cost) {
340+
const n = cost.length;
341+
const f = Array(n + 1).fill(0);
342+
for (let i = 2; i <= n; ++i) {
343+
f[i] = Math.min(f[i - 1] + cost[i - 1], f[i - 2] + cost[i - 2]);
344+
}
345+
return f[n];
346+
}
347+
```
348+
181349
<!-- tabs:end -->
182350

183351
<!-- solution:end -->
184352

185353
<!-- solution:start -->
186354

187-
### Solution 2
355+
### Solution 3: Dynamic Programming (Space Optimization)
356+
357+
We notice that the state transition equation for $f[i]$ only depends on $f[i - 1]$ and $f[i - 2]$. Therefore, we can use two variables $f$ and $g$ to alternately record the values of $f[i - 2]$ and $f[i - 1]$, thus optimizing the space complexity to $O(1)$.
188358

189359
<!-- tabs:start -->
190360

@@ -248,25 +418,11 @@ func minCostClimbingStairs(cost []int) int {
248418

249419
```ts
250420
function minCostClimbingStairs(cost: number[]): number {
251-
let a = 0,
252-
b = 0;
421+
let [f, g] = [0, 0];
253422
for (let i = 1; i < cost.length; ++i) {
254-
[a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])];
423+
[f, g] = [g, Math.min(f + cost[i - 1], g + cost[i])];
255424
}
256-
return b;
257-
}
258-
```
259-
260-
#### JavaScript
261-
262-
```js
263-
function minCostClimbingStairs(cost) {
264-
let a = 0,
265-
b = 0;
266-
for (let i = 1; i < cost.length; ++i) {
267-
[a, b] = [b, Math.min(a + cost[i - 1], b + cost[i])];
268-
}
269-
return b;
425+
return g;
270426
}
271427
```
272428

@@ -286,53 +442,15 @@ impl Solution {
286442
}
287443
```
288444

289-
<!-- tabs:end -->
290-
291-
<!-- solution:end -->
292-
293-
<!-- solution:start -->
294-
295-
### Solution 3: Dynamic Programming. Recursion and top-down approach
296-
297-
<!-- tabs:start -->
298-
299-
#### TypeScript
300-
301-
```ts
302-
function minCostClimbingStairs(cost: number[]): number {
303-
const n = cost.length;
304-
const cache = Array(n).fill(-1);
305-
306-
const fn = (i: number): number => {
307-
if (i <= 1) return cost[i];
308-
if (cache[i] !== undefined && cache[i] !== -1) return cache[i];
309-
310-
cache[i] = (cost[i] ?? 0) + Math.min(fn(i - 1), fn(i - 2));
311-
312-
return cache[i];
313-
};
314-
315-
return fn(n);
316-
}
317-
```
318-
319445
#### JavaScript
320446

321447
```js
322448
function minCostClimbingStairs(cost) {
323-
const n = cost.length;
324-
const cache = Array(n).fill(-1);
325-
326-
const fn = i => {
327-
if (i <= 1) return cost[i];
328-
if (cache[i] !== undefined && cache[i] !== -1) return cache[i];
329-
330-
cache[i] = (cost[i] ?? 0) + Math.min(fn(i - 1), fn(i - 2));
331-
332-
return cache[i];
333-
};
334-
335-
return fn(n);
449+
let [f, g] = [0, 0];
450+
for (let i = 1; i < cost.length; ++i) {
451+
[f, g] = [g, Math.min(f + cost[i - 1], g + cost[i])];
452+
}
453+
return g;
336454
}
337455
```
338456

0 commit comments

Comments
 (0)