Skip to content

Commit 3f6a34f

Browse files
authored
feat: add solutions to lc problem: No.3154 (doocs#2842)
No.3154.Find Number of Ways to Reach the K-th Stair
1 parent ee7ddb9 commit 3f6a34f

File tree

7 files changed

+396
-8
lines changed

7 files changed

+396
-8
lines changed

solution/3100-3199/3154.Find Number of Ways to Reach the K-th Stair/README.md

+138-4
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,166 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3100-3199/3154.Fi
107107

108108
<!-- solution:start -->
109109

110-
### 方法一
110+
### 方法一:记忆化搜索
111+
112+
我们设计一个函数 $\text{dfs}(i, j, \text{jump})$,表示当前位于第 $i$ 级台阶,且进行了 $j$ 次操作 $1$ 和 $\text{jump}$ 次操作 $2$,到达第 $k$ 级台阶的方案数。那么答案就是 $\text{dfs}(1, 0, 0)$。
113+
114+
函数 $\text{dfs}(i, j, \text{jump})$ 的计算过程如下:
115+
116+
- 如果 $i > k + 1$,由于无法连续两次向下走,所以无法再到达第 $k$ 级台阶,返回 $0$;
117+
- 如果 $i = k$,表示已经到达第 $k$ 级台阶,答案初始化为 $1$,然后继续计算;
118+
- 如果 $i > 0$ 且 $j = 0$,表示可以向下走,递归计算 $\text{dfs}(i - 1, 1, \text{jump})$;
119+
- 递归计算 $\text{dfs}(i + 2^{\text{jump}}, 0, \text{jump} + 1)$,累加到答案中。
120+
121+
为了避免重复计算,我们使用记忆化搜索,将已经计算过的状态保存起来。
122+
123+
时间复杂度 $(\log ^2 k)$,空间复杂度 $(\log ^2 k)$。
111124

112125
<!-- tabs:start -->
113126

114127
#### Python3
115128

116129
```python
117-
130+
class Solution:
131+
def waysToReachStair(self, k: int) -> int:
132+
@cache
133+
def dfs(i: int, j: int, jump: int) -> int:
134+
if i > k + 1:
135+
return 0
136+
ans = int(i == k)
137+
if i > 0 and j == 0:
138+
ans += dfs(i - 1, 1, jump)
139+
ans += dfs(i + (1 << jump), 0, jump + 1)
140+
return ans
141+
142+
return dfs(1, 0, 0)
118143
```
119144

120145
#### Java
121146

122147
```java
123-
148+
class Solution {
149+
private Map<Long, Integer> f = new HashMap<>();
150+
private int k;
151+
152+
public int waysToReachStair(int k) {
153+
this.k = k;
154+
return dfs(1, 0, 0);
155+
}
156+
157+
private int dfs(int i, int j, int jump) {
158+
if (i > k + 1) {
159+
return 0;
160+
}
161+
long key = ((long) i << 32) | jump << 1 | j;
162+
if (f.containsKey(key)) {
163+
return f.get(key);
164+
}
165+
int ans = i == k ? 1 : 0;
166+
if (i > 0 && j == 0) {
167+
ans += dfs(i - 1, 1, jump);
168+
}
169+
ans += dfs(i + (1 << jump), 0, jump + 1);
170+
f.put(key, ans);
171+
return ans;
172+
}
173+
}
124174
```
125175

126176
#### C++
127177

128178
```cpp
129-
179+
class Solution {
180+
public:
181+
int waysToReachStair(int k) {
182+
this->k = k;
183+
return dfs(1, 0, 0);
184+
}
185+
186+
private:
187+
unordered_map<long long, int> f;
188+
int k;
189+
190+
int dfs(int i, int j, int jump) {
191+
if (i > k + 1) {
192+
return 0;
193+
}
194+
long long key = ((long long) i << 32) | jump << 1 | j;
195+
if (f.contains(key)) {
196+
return f[key];
197+
}
198+
int ans = i == k ? 1 : 0;
199+
if (i > 0 && j == 0) {
200+
ans += dfs(i - 1, 1, jump);
201+
}
202+
ans += dfs(i + (1 << jump), 0, jump + 1);
203+
f[key] = ans;
204+
return ans;
205+
}
206+
};
130207
```
131208

132209
#### Go
133210

134211
```go
212+
func waysToReachStair(k int) int {
213+
f := map[int]int{}
214+
var dfs func(i, j, jump int) int
215+
dfs = func(i, j, jump int) int {
216+
if i > k+1 {
217+
return 0
218+
}
219+
key := (i << 32) | jump<<1 | j
220+
if v, has := f[key]; has {
221+
return v
222+
}
223+
ans := 0
224+
if i == k {
225+
ans++
226+
}
227+
if i > 0 && j == 0 {
228+
ans += dfs(i-1, 1, jump)
229+
}
230+
ans += dfs(i+(1<<jump), 0, jump+1)
231+
f[key] = ans
232+
return ans
233+
}
234+
return dfs(1, 0, 0)
235+
}
236+
```
237+
238+
#### TypeScript
239+
240+
```ts
241+
function waysToReachStair(k: number): number {
242+
const f: Map<bigint, number> = new Map();
243+
244+
const dfs = (i: number, j: number, jump: number): number => {
245+
if (i > k + 1) {
246+
return 0;
247+
}
248+
249+
const key: bigint = (BigInt(i) << BigInt(32)) | BigInt(jump << 1) | BigInt(j);
250+
if (f.has(key)) {
251+
return f.get(key)!;
252+
}
253+
254+
let ans: number = 0;
255+
if (i === k) {
256+
ans++;
257+
}
258+
259+
if (i > 0 && j === 0) {
260+
ans += dfs(i - 1, 1, jump);
261+
}
262+
263+
ans += dfs(i + (1 << jump), 0, jump + 1);
264+
f.set(key, ans);
265+
return ans;
266+
};
135267

268+
return dfs(1, 0, 0);
269+
}
136270
```
137271

138272
<!-- tabs:end -->

solution/3100-3199/3154.Find Number of Ways to Reach the K-th Stair/README_EN.md

+138-4
Original file line numberDiff line numberDiff line change
@@ -105,32 +105,166 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3100-3199/3154.Fi
105105

106106
<!-- solution:start -->
107107

108-
### Solution 1
108+
### Solution 1: Memoization Search
109+
110+
We design a function `dfs(i, j, jump)`, which represents the number of ways to reach the $k$th step when currently at the $i$th step, having performed $j$ operation 1's and `jump` operation 2's. The answer is `dfs(1, 0, 0)`.
111+
112+
The calculation process of the function `dfs(i, j, jump)` is as follows:
113+
114+
- If $i > k + 1$, since we cannot go down twice in a row, we cannot reach the $k$th step again, so return $0$;
115+
- If $i = k$, it means that we have reached the $k$th step. The answer is initialized to $1$, and then continue to calculate;
116+
- If $i > 0$ and $j = 0$, it means that we can go down, recursively calculate `dfs(i - 1, 1, jump)`;
117+
- Recursively calculate `dfs(i + 2^{jump}, 0, jump + 1)`, and add it to the answer.
118+
119+
To avoid repeated calculations, we use memoization search to save the calculated states.
120+
121+
The time complexity is $O(\log^2 k)$, and the space complexity is $O(\log^2 k)$.
109122

110123
<!-- tabs:start -->
111124

112125
#### Python3
113126

114127
```python
115-
128+
class Solution:
129+
def waysToReachStair(self, k: int) -> int:
130+
@cache
131+
def dfs(i: int, j: int, jump: int) -> int:
132+
if i > k + 1:
133+
return 0
134+
ans = int(i == k)
135+
if i > 0 and j == 0:
136+
ans += dfs(i - 1, 1, jump)
137+
ans += dfs(i + (1 << jump), 0, jump + 1)
138+
return ans
139+
140+
return dfs(1, 0, 0)
116141
```
117142

118143
#### Java
119144

120145
```java
121-
146+
class Solution {
147+
private Map<Long, Integer> f = new HashMap<>();
148+
private int k;
149+
150+
public int waysToReachStair(int k) {
151+
this.k = k;
152+
return dfs(1, 0, 0);
153+
}
154+
155+
private int dfs(int i, int j, int jump) {
156+
if (i > k + 1) {
157+
return 0;
158+
}
159+
long key = ((long) i << 32) | jump << 1 | j;
160+
if (f.containsKey(key)) {
161+
return f.get(key);
162+
}
163+
int ans = i == k ? 1 : 0;
164+
if (i > 0 && j == 0) {
165+
ans += dfs(i - 1, 1, jump);
166+
}
167+
ans += dfs(i + (1 << jump), 0, jump + 1);
168+
f.put(key, ans);
169+
return ans;
170+
}
171+
}
122172
```
123173

124174
#### C++
125175

126176
```cpp
127-
177+
class Solution {
178+
public:
179+
int waysToReachStair(int k) {
180+
this->k = k;
181+
return dfs(1, 0, 0);
182+
}
183+
184+
private:
185+
unordered_map<long long, int> f;
186+
int k;
187+
188+
int dfs(int i, int j, int jump) {
189+
if (i > k + 1) {
190+
return 0;
191+
}
192+
long long key = ((long long) i << 32) | jump << 1 | j;
193+
if (f.contains(key)) {
194+
return f[key];
195+
}
196+
int ans = i == k ? 1 : 0;
197+
if (i > 0 && j == 0) {
198+
ans += dfs(i - 1, 1, jump);
199+
}
200+
ans += dfs(i + (1 << jump), 0, jump + 1);
201+
f[key] = ans;
202+
return ans;
203+
}
204+
};
128205
```
129206

130207
#### Go
131208

132209
```go
210+
func waysToReachStair(k int) int {
211+
f := map[int]int{}
212+
var dfs func(i, j, jump int) int
213+
dfs = func(i, j, jump int) int {
214+
if i > k+1 {
215+
return 0
216+
}
217+
key := (i << 32) | jump<<1 | j
218+
if v, has := f[key]; has {
219+
return v
220+
}
221+
ans := 0
222+
if i == k {
223+
ans++
224+
}
225+
if i > 0 && j == 0 {
226+
ans += dfs(i-1, 1, jump)
227+
}
228+
ans += dfs(i+(1<<jump), 0, jump+1)
229+
f[key] = ans
230+
return ans
231+
}
232+
return dfs(1, 0, 0)
233+
}
234+
```
235+
236+
#### TypeScript
237+
238+
```ts
239+
function waysToReachStair(k: number): number {
240+
const f: Map<bigint, number> = new Map();
241+
242+
const dfs = (i: number, j: number, jump: number): number => {
243+
if (i > k + 1) {
244+
return 0;
245+
}
246+
247+
const key: bigint = (BigInt(i) << BigInt(32)) | BigInt(jump << 1) | BigInt(j);
248+
if (f.has(key)) {
249+
return f.get(key)!;
250+
}
251+
252+
let ans: number = 0;
253+
if (i === k) {
254+
ans++;
255+
}
256+
257+
if (i > 0 && j === 0) {
258+
ans += dfs(i - 1, 1, jump);
259+
}
260+
261+
ans += dfs(i + (1 << jump), 0, jump + 1);
262+
f.set(key, ans);
263+
return ans;
264+
};
133265

266+
return dfs(1, 0, 0);
267+
}
134268
```
135269

136270
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
public:
3+
int waysToReachStair(int k) {
4+
this->k = k;
5+
return dfs(1, 0, 0);
6+
}
7+
8+
private:
9+
unordered_map<long long, int> f;
10+
int k;
11+
12+
int dfs(int i, int j, int jump) {
13+
if (i > k + 1) {
14+
return 0;
15+
}
16+
long long key = ((long long) i << 32) | jump << 1 | j;
17+
if (f.contains(key)) {
18+
return f[key];
19+
}
20+
int ans = i == k ? 1 : 0;
21+
if (i > 0 && j == 0) {
22+
ans += dfs(i - 1, 1, jump);
23+
}
24+
ans += dfs(i + (1 << jump), 0, jump + 1);
25+
f[key] = ans;
26+
return ans;
27+
}
28+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
func waysToReachStair(k int) int {
2+
f := map[int]int{}
3+
var dfs func(i, j, jump int) int
4+
dfs = func(i, j, jump int) int {
5+
if i > k+1 {
6+
return 0
7+
}
8+
key := (i << 32) | jump<<1 | j
9+
if v, has := f[key]; has {
10+
return v
11+
}
12+
ans := 0
13+
if i == k {
14+
ans++
15+
}
16+
if i > 0 && j == 0 {
17+
ans += dfs(i-1, 1, jump)
18+
}
19+
ans += dfs(i+(1<<jump), 0, jump+1)
20+
f[key] = ans
21+
return ans
22+
}
23+
return dfs(1, 0, 0)
24+
}

0 commit comments

Comments
 (0)