Skip to content

Commit efac6f0

Browse files
authored
feat: add solutions to lc problem: No.2930 (doocs#1969)
No.2930.Number of Strings Which Can Be Rearranged to Contain Substring
1 parent 1a7073e commit efac6f0

File tree

7 files changed

+648
-0
lines changed

7 files changed

+648
-0
lines changed

solution/2900-2999/2930.Number of Strings Which Can Be Rearranged to Contain Substring/README.md

+271
Original file line numberDiff line numberDiff line change
@@ -53,34 +53,305 @@
5353

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

56+
**方法一:记忆化搜索**
57+
58+
我们设计一个函数 $dfs(i, l, e, t)$,表示当前剩余字符串长度为 $i$,且已至少有 $l$ 个字符 `'l'`, $e$ 个字符 `'e'` 和 $t$ 个字符 `'t'`,构成的字符串是一个好字符串的方案数。那么答案为 $dfs(n, 0, 0, 0)$。
59+
60+
函数 $dfs(i, l, e, t)$ 的执行逻辑如下:
61+
62+
如果 $i = 0$,说明当前字符串已经构造完毕,如果 $l = 1$, $e = 2$ 且 $t = 1$,说明当前字符串是一个好字符串,返回 $1$,否则返回 $0$。
63+
64+
否则,我们可以考虑在当前位置添加除 `'l'`, `'e'`, `'t'` 以外的任意一个小写字母,一共有 $23$ 种,那么此时得到的方案数为 $dfs(i - 1, l, e, t) \times 23$。
65+
66+
我们也可以考虑在当前位置添加 `'l'`,此时得到的方案数为 $dfs(i - 1, \min(1, l + 1), e, t)$。同理,添加 `'e'``'t'` 的方案数分别为 $dfs(i - 1, l, \min(2, e + 1), t)$ 和 $dfs(i - 1, l, e, \min(1, t + 1))$。累加起来,并对 $10^9 + 7$ 取模,即可得到 $dfs(i, l, e, t)$ 的值。
67+
68+
为了避免重复计算,我们可以使用记忆化搜索。
69+
70+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串长度。
71+
72+
**方法二:逆向思维 + 容斥原理**
73+
74+
我们可以考虑逆向思维,即计算不包含子字符串 `"leet"` 的字符串数目,然后用总数减去该数目即可。
75+
76+
我们分成以下几种情况:
77+
78+
- 情况 $a$:表示字符串中不包含字符 `'l'` 的方案数,那么有 $a = 25^n$。
79+
- 情况 $b$:与 $a$ 类似,表示字符串中不包含字符 `'t'` 的方案数,那么有 $b = 25^n$。
80+
- 情况 $c$:表示字符串中不包含字符 `'e'` 或者只包含一个字符 `'e'` 的方案数,那么有 $c = 25^n + n \times 25^{n - 1}$。
81+
- 情况 $ab$:表示字符串中不包含字符 `'l'``'t'` 的方案数,那么有 $ab = 24^n$。
82+
- 情况 $ac$:表示字符串中不包含字符 `'l'``'e'` 或者只包含一个字符 `'e'` 的方案数,那么有 $ac = 24^n + n \times 24^{n - 1}$。
83+
- 情况 $bc$:与 $ac$ 类似,表示字符串中不包含字符 `'t'``'e'` 或者只包含一个字符 `'e'` 的方案数,那么有 $bc = 24^n + n \times 24^{n - 1}$。
84+
- 情况 $abc$:表示字符串中不包含字符 `'l'``'t'``'e'` 或者只包含一个字符 `'e'` 的方案数,那么有 $abc = 23^n + n \times 23^{n - 1}$。
85+
86+
那么根据容斥原理,可以得到 $a + b + c - ab - ac - bc + abc$,就是不包含子字符串 `"leet"` 的字符串数目。
87+
88+
而总数 $tot = 26^n$,所以答案为 $tot - (a + b + c - ab - ac - bc + abc)$,注意要对 $10^9 + 7$ 取模。
89+
90+
时间复杂度 $O(\log n)$,其中 $n$ 为字符串长度。空间复杂度 $O(1)$。
91+
5692
<!-- tabs:start -->
5793

5894
### **Python3**
5995

6096
<!-- 这里可写当前语言的特殊实现逻辑 -->
6197

6298
```python
99+
class Solution:
100+
def stringCount(self, n: int) -> int:
101+
@cache
102+
def dfs(i: int, l: int, e: int, t: int) -> int:
103+
if i == 0:
104+
return int(l == 1 and e == 2 and t == 1)
105+
a = dfs(i - 1, l, e, t) * 23 % mod
106+
b = dfs(i - 1, min(1, l + 1), e, t)
107+
c = dfs(i - 1, l, min(2, e + 1), t)
108+
d = dfs(i - 1, l, e, min(1, t + 1))
109+
return (a + b + c + d) % mod
110+
111+
mod = 10**9 + 7
112+
return dfs(n, 0, 0, 0)
113+
```
63114

115+
```python
116+
class Solution:
117+
def stringCount(self, n: int) -> int:
118+
mod = 10**9 + 7
119+
a = b = pow(25, n, mod)
120+
c = pow(25, n, mod) + n * pow(25, n - 1, mod)
121+
ab = pow(24, n, mod)
122+
ac = bc = (pow(24, n, mod) + n * pow(24, n - 1, mod)) % mod
123+
abc = (pow(23, n, mod) + n * pow(23, n - 1, mod)) % mod
124+
tot = pow(26, n, mod)
125+
return (tot - (a + b + c - ab - ac - bc + abc)) % mod
64126
```
65127

66128
### **Java**
67129

68130
<!-- 这里可写当前语言的特殊实现逻辑 -->
69131

70132
```java
133+
class Solution {
134+
private final int mod = (int) 1e9 + 7;
135+
private Long[][][][] f;
136+
137+
public int stringCount(int n) {
138+
f = new Long[n + 1][2][3][2];
139+
return (int) dfs(n, 0, 0, 0);
140+
}
141+
142+
private long dfs(int i, int l, int e, int t) {
143+
if (i == 0) {
144+
return l == 1 && e == 2 && t == 1 ? 1 : 0;
145+
}
146+
if (f[i][l][e][t] != null) {
147+
return f[i][l][e][t];
148+
}
149+
long a = dfs(i - 1, l, e, t) * 23 % mod;
150+
long b = dfs(i - 1, Math.min(1, l + 1), e, t);
151+
long c = dfs(i - 1, l, Math.min(2, e + 1), t);
152+
long d = dfs(i - 1, l, e, Math.min(1, t + 1));
153+
return f[i][l][e][t] = (a + b + c + d) % mod;
154+
}
155+
}
156+
```
71157

158+
```java
159+
class Solution {
160+
private final int mod = (int) 1e9 + 7;
161+
162+
public int stringCount(int n) {
163+
long a = qpow(25, n);
164+
long b = a;
165+
long c = (qpow(25, n) + n * qpow(25, n - 1) % mod) % mod;
166+
long ab = qpow(24, n);
167+
long ac = (qpow(24, n) + n * qpow(24, n - 1) % mod) % mod;
168+
long bc = ac;
169+
long abc = (qpow(23, n) + n * qpow(23, n - 1) % mod) % mod;
170+
long tot = qpow(26, n);
171+
return (int) ((tot - (a + b + c - ab - ac - bc + abc)) % mod + mod) % mod;
172+
}
173+
174+
private long qpow(long a, int n) {
175+
long ans = 1;
176+
for (; n > 0; n >>= 1) {
177+
if ((n & 1) == 1) {
178+
ans = ans * a % mod;
179+
}
180+
a = a * a % mod;
181+
}
182+
return ans;
183+
}
184+
}
72185
```
73186

74187
### **C++**
75188

76189
```cpp
190+
class Solution {
191+
public:
192+
int stringCount(int n) {
193+
const int mod = 1e9 + 7;
194+
using ll = long long;
195+
ll f[n + 1][2][3][2];
196+
memset(f, -1, sizeof(f));
197+
function<ll(int, int, int, int)> dfs = [&](int i, int l, int e, int t) -> ll {
198+
if (i == 0) {
199+
return l == 1 && e == 2 && t == 1 ? 1 : 0;
200+
}
201+
if (f[i][l][e][t] != -1) {
202+
return f[i][l][e][t];
203+
}
204+
ll a = dfs(i - 1, l, e, t) * 23 % mod;
205+
ll b = dfs(i - 1, min(1, l + 1), e, t) % mod;
206+
ll c = dfs(i - 1, l, min(2, e + 1), t) % mod;
207+
ll d = dfs(i - 1, l, e, min(1, t + 1)) % mod;
208+
return f[i][l][e][t] = (a + b + c + d) % mod;
209+
};
210+
return dfs(n, 0, 0, 0);
211+
}
212+
};
213+
```
77214
215+
```cpp
216+
class Solution {
217+
public:
218+
int stringCount(int n) {
219+
const int mod = 1e9 + 7;
220+
using ll = long long;
221+
auto qpow = [&](ll a, int n) {
222+
ll ans = 1;
223+
for (; n; n >>= 1) {
224+
if (n & 1) {
225+
ans = ans * a % mod;
226+
}
227+
a = a * a % mod;
228+
}
229+
return ans;
230+
};
231+
ll a = qpow(25, n);
232+
ll b = a;
233+
ll c = (qpow(25, n) + n * qpow(25, n - 1) % mod) % mod;
234+
ll ab = qpow(24, n);
235+
ll ac = (qpow(24, n) + n * qpow(24, n - 1) % mod) % mod;
236+
ll bc = ac;
237+
ll abc = (qpow(23, n) + n * qpow(23, n - 1) % mod) % mod;
238+
ll tot = qpow(26, n);
239+
return ((tot - (a + b + c - ab - ac - bc + abc)) % mod + mod) % mod;
240+
}
241+
};
78242
```
79243

80244
### **Go**
81245

82246
```go
247+
func stringCount(n int) int {
248+
const mod int = 1e9 + 7
249+
f := make([][2][3][2]int, n+1)
250+
for i := range f {
251+
for j := range f[i] {
252+
for k := range f[i][j] {
253+
for l := range f[i][j][k] {
254+
f[i][j][k][l] = -1
255+
}
256+
}
257+
}
258+
}
259+
var dfs func(i, l, e, t int) int
260+
dfs = func(i, l, e, t int) int {
261+
if i == 0 {
262+
if l == 1 && e == 2 && t == 1 {
263+
return 1
264+
}
265+
return 0
266+
}
267+
if f[i][l][e][t] == -1 {
268+
a := dfs(i-1, l, e, t) * 23 % mod
269+
b := dfs(i-1, min(1, l+1), e, t)
270+
c := dfs(i-1, l, min(2, e+1), t)
271+
d := dfs(i-1, l, e, min(1, t+1))
272+
f[i][l][e][t] = (a + b + c + d) % mod
273+
}
274+
return f[i][l][e][t]
275+
}
276+
return dfs(n, 0, 0, 0)
277+
}
278+
```
279+
280+
```go
281+
func stringCount(n int) int {
282+
const mod int = 1e9 + 7
283+
qpow := func(a, n int) int {
284+
ans := 1
285+
for ; n > 0; n >>= 1 {
286+
if n&1 == 1 {
287+
ans = ans * a % mod
288+
}
289+
a = a * a % mod
290+
}
291+
return ans
292+
}
293+
a := qpow(25, n)
294+
b := a
295+
c := qpow(25, n) + n*qpow(25, n-1)
296+
ab := qpow(24, n)
297+
ac := (qpow(24, n) + n*qpow(24, n-1)) % mod
298+
bc := ac
299+
abc := (qpow(23, n) + n*qpow(23, n-1)) % mod
300+
tot := qpow(26, n)
301+
return ((tot-(a+b+c-ab-ac-bc+abc))%mod + mod) % mod
302+
}
303+
```
304+
305+
### **TypeScript**
306+
307+
```ts
308+
function stringCount(n: number): number {
309+
const mod = 10 ** 9 + 7;
310+
const f: number[][][][] = Array.from({ length: n + 1 }, () =>
311+
Array.from({ length: 2 }, () =>
312+
Array.from({ length: 3 }, () => Array.from({ length: 2 }, () => -1)),
313+
),
314+
);
315+
const dfs = (i: number, l: number, e: number, t: number): number => {
316+
if (i === 0) {
317+
return l === 1 && e === 2 && t === 1 ? 1 : 0;
318+
}
319+
if (f[i][l][e][t] !== -1) {
320+
return f[i][l][e][t];
321+
}
322+
const a = (dfs(i - 1, l, e, t) * 23) % mod;
323+
const b = dfs(i - 1, Math.min(1, l + 1), e, t);
324+
const c = dfs(i - 1, l, Math.min(2, e + 1), t);
325+
const d = dfs(i - 1, l, e, Math.min(1, t + 1));
326+
return (f[i][l][e][t] = (a + b + c + d) % mod);
327+
};
328+
return dfs(n, 0, 0, 0);
329+
}
330+
```
83331

332+
```ts
333+
function stringCount(n: number): number {
334+
const mod = BigInt(10 ** 9 + 7);
335+
const qpow = (a: bigint, n: number): bigint => {
336+
let ans = 1n;
337+
for (; n; n >>>= 1) {
338+
if (n & 1) {
339+
ans = (ans * a) % mod;
340+
}
341+
a = (a * a) % mod;
342+
}
343+
return ans;
344+
};
345+
const a = qpow(25n, n);
346+
const b = a;
347+
const c = (qpow(25n, n) + ((BigInt(n) * qpow(25n, n - 1)) % mod)) % mod;
348+
const ab = qpow(24n, n);
349+
const ac = (qpow(24n, n) + ((BigInt(n) * qpow(24n, n - 1)) % mod)) % mod;
350+
const bc = ac;
351+
const abc = (qpow(23n, n) + ((BigInt(n) * qpow(23n, n - 1)) % mod)) % mod;
352+
const tot = qpow(26n, n);
353+
return Number((((tot - (a + b + c - ab - ac - bc + abc)) % mod) + mod) % mod);
354+
}
84355
```
85356

86357
### **...**

0 commit comments

Comments
 (0)