Skip to content

Commit c917eeb

Browse files
committed
feat: add solutions to lc problem: No.2400
No.2400.Number of Ways to Reach a Position After Exactly k Steps
1 parent 2dce477 commit c917eeb

File tree

11 files changed

+240
-175
lines changed

11 files changed

+240
-175
lines changed

solution/2300-2399/2393.Count Strictly Increasing Subarrays/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class Solution {
133133
return ans;
134134
}
135135
}
136-
``
136+
```
137137

138138
### **C++**
139139

solution/2300-2399/2393.Count Strictly Increasing Subarrays/README_EN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class Solution {
111111
return ans;
112112
}
113113
}
114-
``
114+
```
115115

116116
### **C++**
117117

solution/2300-2399/2396.Strictly Palindromic Number/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@
4646

4747
**方法一:脑筋急转弯**
4848

49-
当 $n=4$ 时,二进制表示为 `100`,不是回文串;
49+
当 $n=4$ 时,二进制表示为 $100$,不是回文串;
5050

51-
当 $n\gt 4$ 时,$n-2$ 的二进制表示为 `12`,不是回文串。
51+
当 $n \gt 4$ 时,此时 $n-2$ 的二进制表示为 $12$,不是回文串。
5252

5353
因此,直接返回 `false`
5454

solution/2300-2399/2399.Check Distances Between Same Letters/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
**方法一:哈希表**
56+
**方法一:数组或哈希表**
5757

58-
用哈希表记录每个字母出现的下标,然后遍历哈希表,判断每个字母的下标之差是否等于 `distance` 中对应的值。
58+
我们可以用哈希表 $d$ 记录每个字母出现的下标,然后遍历哈希表,判断每个字母的下标之差是否等于 `distance` 中对应的值。
5959

60-
时间复杂度 $O(n)$,其中 $n$ 为字符串 `s` 的长度。
60+
时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。
6161

6262
<!-- tabs:start -->
6363

solution/2400-2499/2400.Number of Ways to Reach a Position After Exactly k Steps/README.md

Lines changed: 87 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,20 @@
4646

4747
**方法一:记忆化搜索**
4848

49-
时间复杂度 $O(k^2)$。
49+
我们设计一个函数 $dfs(i, j)$,表示当前位置距离目标位置的距离为 $i$,还剩 $j$ 步,有多少种方法到达目标位置。那么答案就是 $dfs(abs(startPos - endPos), k)$。
50+
51+
函数 $dfs(i, j)$ 的计算方式如下:
52+
53+
- 如果 $i \gt j$ 或者 $j \lt 0$,说明当前位置距离目标位置的距离大于剩余步数,或者剩余步数为负数,此时无法到达目标位置,返回 $0$;
54+
- 如果 $j = 0$,说明剩余步数为 $0$,此时只有当前位置距离目标位置的距离为 $0$ 时才能到达目标位置,否则无法到达目标位置,返回 $1$ 或者 $0$;
55+
- 否则,当前位置距离目标位置的距离为 $i$,还剩 $j$ 步,那么有两种方法到达目标位置:
56+
- 向左移动一步,此时当前位置距离目标位置的距离为 $i + 1$,还剩 $j - 1$ 步,方法数为 $dfs(i + 1, j - 1)$;
57+
- 向右移动一步,此时当前位置距离目标位置的距离为 $abs(i - 1)$,还剩 $j - 1$ 步,方法数为 $dfs(abs(i - 1), j - 1)$;
58+
- 最后,返回两种方法的和对 $10^9 + 7$ 取余的结果。
59+
60+
为了避免重复计算,我们使用记忆化搜索,即使用一个二维数组 $f$ 记录函数 $dfs(i, j)$ 的结果,当函数 $dfs(i, j)$ 被调用时,如果 $f[i][j]$ 不为 $-1$,则直接返回 $f[i][j]$,否则计算 $f[i][j]$ 的值,并返回 $f[i][j]$。
61+
62+
时间复杂度 $O(k^2)$,空间复杂度 $O(k^2)$。其中 $k$ 为题目给定的步数。
5063

5164
<!-- tabs:start -->
5265

@@ -58,14 +71,14 @@
5871
class Solution:
5972
def numberOfWays(self, startPos: int, endPos: int, k: int) -> int:
6073
@cache
61-
def dfs(d, k):
62-
if k < 0 or abs(d) > k:
74+
def dfs(i: int, j: int) -> int:
75+
if i > j or j < 0:
6376
return 0
64-
if k == 0:
65-
return d == 0
66-
res = dfs(d - 1, k - 1) + dfs(d + 1, k - 1)
67-
return res % (10**9 + 7)
77+
if j == 0:
78+
return 1 if i == 0 else 0
79+
return (dfs(i + 1, j - 1) + dfs(abs(i - 1), j - 1)) % mod
6880

81+
mod = 10**9 + 7
6982
return dfs(abs(startPos - endPos), k)
7083
```
7184

@@ -75,34 +88,27 @@ class Solution:
7588

7689
```java
7790
class Solution {
78-
private static final int MOD = (int) 1e9 + 7;
79-
private int[][] f = new int[3010][3010];
80-
private int j;
91+
private Integer[][] f;
92+
private final int mod = (int) 1e9 + 7;
8193

8294
public int numberOfWays(int startPos, int endPos, int k) {
83-
startPos += 1000;
84-
endPos += 1000;
85-
for (var e : f) {
86-
Arrays.fill(e, -1);
87-
}
88-
j = endPos;
89-
return dfs(startPos, k);
95+
f = new Integer[k + 1][k + 1];
96+
return dfs(Math.abs(startPos - endPos), k);
9097
}
9198

92-
private int dfs(int i, int k) {
93-
if (Math.abs(i - j) > k) {
99+
private int dfs(int i, int j) {
100+
if (i > j || j < 0) {
94101
return 0;
95102
}
96-
if (f[i][k] != -1) {
97-
return f[i][k];
103+
if (j == 0) {
104+
return i == 0 ? 1 : 0;
98105
}
99-
if (k == 0) {
100-
return i == j ? 1 : 0;
106+
if (f[i][j] != null) {
107+
return f[i][j];
101108
}
102-
int res = dfs(i + 1, k - 1) + dfs(i - 1, k - 1);
103-
res %= MOD;
104-
f[i][k] = res;
105-
return res;
109+
int ans = dfs(i + 1, j - 1) + dfs(Math.abs(i - 1), j - 1);
110+
ans %= mod;
111+
return f[i][j] = ans;
106112
}
107113
}
108114
```
@@ -112,23 +118,24 @@ class Solution {
112118
```cpp
113119
class Solution {
114120
public:
115-
unordered_map<int, int> f;
116-
int mod = 1e9 + 7;
117-
int j;
118-
119121
int numberOfWays(int startPos, int endPos, int k) {
120-
j = endPos;
121-
return dfs(startPos, k);
122-
}
123-
124-
int dfs(int i, int k) {
125-
if (f.count(i * 10000 + k)) return f[i * 10000 + k];
126-
if (abs(i - j) > k) return 0;
127-
if (k == 0) return i == j;
128-
int res = dfs(i - 1, k - 1) + dfs(i + 1, k - 1);
129-
res %= mod;
130-
f[i * 10000 + k] = res;
131-
return res;
122+
const int mod = 1e9 + 7;
123+
int f[k + 1][k + 1];
124+
memset(f, -1, sizeof(f));
125+
function<int(int, int)> dfs = [&](int i, int j) -> int {
126+
if (i > j || j < 0) {
127+
return 0;
128+
}
129+
if (j == 0) {
130+
return i == 0 ? 1 : 0;
131+
}
132+
if (f[i][j] != -1) {
133+
return f[i][j];
134+
}
135+
f[i][j] = (dfs(i + 1, j - 1) + dfs(abs(i - 1), j - 1)) % mod;
136+
return f[i][j];
137+
};
138+
return dfs(abs(startPos - endPos), k);
132139
}
133140
};
134141
```
@@ -137,27 +144,32 @@ public:
137144
138145
```go
139146
func numberOfWays(startPos int, endPos int, k int) int {
140-
f := map[int]int{}
141-
var dfs func(i, k int) int
142-
dfs = func(i, k int) int {
143-
if abs(i-endPos) > k {
147+
const mod = 1e9 + 7
148+
f := make([][]int, k+1)
149+
for i := range f {
150+
f[i] = make([]int, k+1)
151+
for j := range f[i] {
152+
f[i][j] = -1
153+
}
154+
}
155+
var dfs func(i, j int) int
156+
dfs = func(i, j int) int {
157+
if i > j || j < 0 {
144158
return 0
145159
}
146-
if k == 0 {
147-
if i == endPos {
160+
if j == 0 {
161+
if i == 0 {
148162
return 1
149163
}
150164
return 0
151165
}
152-
if v, ok := f[i*10000+k]; ok {
153-
return v
166+
if f[i][j] != -1 {
167+
return f[i][j]
154168
}
155-
res := dfs(i+1, k-1) + dfs(i-1, k-1)
156-
res %= 1e9 + 7
157-
f[i*10000+k] = res
158-
return res
169+
f[i][j] = (dfs(i+1, j-1) + dfs(abs(i-1), j-1)) % mod
170+
return f[i][j]
159171
}
160-
return dfs(startPos, k)
172+
return dfs(abs(startPos-endPos), k)
161173
}
162174
163175
func abs(x int) int {
@@ -171,7 +183,25 @@ func abs(x int) int {
171183
### **TypeScript**
172184

173185
```ts
174-
186+
function numberOfWays(startPos: number, endPos: number, k: number): number {
187+
const mod = 10 ** 9 + 7;
188+
const f = new Array(k + 1).fill(0).map(() => new Array(k + 1).fill(-1));
189+
const dfs = (i: number, j: number): number => {
190+
if (i > j || j < 0) {
191+
return 0;
192+
}
193+
if (j === 0) {
194+
return i === 0 ? 1 : 0;
195+
}
196+
if (f[i][j] !== -1) {
197+
return f[i][j];
198+
}
199+
f[i][j] = dfs(i + 1, j - 1) + dfs(Math.abs(i - 1), j - 1);
200+
f[i][j] %= mod;
201+
return f[i][j];
202+
};
203+
return dfs(Math.abs(startPos - endPos), k);
204+
}
175205
```
176206

177207
### **...**

0 commit comments

Comments
 (0)