Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lcp problem: No.25 #3649

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions lcp/LCP 25. 古董键盘/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,159 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2025.%20%E5%8F%A4%

<!-- solution:start -->

### 方法一:动态规划

我们定义 $f[i][j]$ 表示按了 $i$ 次按键,且使用了前 $j$ 个字母的方案数。初始时 $f[0]$ 全部为 $1$,表示没有按键时只有一种方案,其余 $f[i][j] = 0$。

对于 $f[i][j]$,我们考虑其转移方式。我们可以枚举第 $j$ 个字母一共使用了多少次,设为 $h$,其中 $0 \leq h \leq \min(i, k)$,那么我们可以从 $f[i - h][j - 1]$ 转移过来,且第 $j$ 个字母可以在 $i$ 次按键中使用 $h$ 次,方案数为 $\binom{i}{h}$。即:

$$
f[i][j] = \sum_{h = 0}^{\min(i, k)} f[i - h][j - 1] \cdot \binom{i}{h}
$$

最终答案即为 $f[n][26]$。

时间复杂度 $O(n \times k \times |\Sigma|)$,空间复杂度 $O(n \times |\Sigma|)$。其中 $|\Sigma|$ 表示字母表大小。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def keyboard(self, k: int, n: int) -> int:
f = [[0] * 27 for _ in range(n + 1)]
f[0] = [1] * 27
mod = 10**9 + 7
for i in range(1, n + 1):
for j in range(1, 27):
for h in range(min(k, i) + 1):
f[i][j] += f[i - h][j - 1] * comb(i, h)
f[i][j] %= mod
return f[n][26]
```

#### Java

```java
class Solution {
public int keyboard(int k, int n) {
int[][] c = new int[n + 1][k + 1];
for (int i = 0; i <= n; ++i) {
c[i][0] = 1;
}
final int mod = (int) 1e9 + 7;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
int[][] f = new int[n + 1][27];
Arrays.fill(f[0], 1);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < 27; ++j) {
for (int h = 0; h <= Math.min(i, k); ++h) {
f[i][j] = (f[i][j] + (int) ((long) f[i - h][j - 1] * c[i][h] % mod)) % mod;
}
}
}
return f[n][26];
}
}
```

#### C++

```cpp
class Solution {
public:
int keyboard(int k, int n) {
int f[n + 1][27];
memset(f, 0, sizeof(f));
for (int j = 0; j < 27; ++j) {
f[0][j] = 1;
}
int c[n + 1][k + 1];
memset(c, 0, sizeof(c));
c[0][0] = 1;
const int mod = 1e9 + 7;
for (int i = 1; i <= n; ++i) {
c[i][0] = 1;
for (int j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < 27; ++j) {
for (int h = 0; h <= min(i, k); ++h) {
f[i][j] = (f[i][j] + 1LL * f[i - h][j - 1] * c[i][h] % mod) % mod;
}
}
}
return f[n][26];
}
};
```

#### Go

```go
func keyboard(k int, n int) int {
c := make([][]int, n+1)
for i := range c {
c[i] = make([]int, k+1)
c[i][0] = 1
}
const mod int = 1e9 + 7
for i := 1; i <= n; i++ {
for j := 1; j <= k; j++ {
c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod
}
}
f := make([][27]int, n+1)
for j := range f[0] {
f[0][j] = 1
}
for i := 1; i <= n; i++ {
for j := 1; j < 27; j++ {
for h := 0; h <= min(i, k); h++ {
f[i][j] = (f[i][j] + f[i-h][j-1]*c[i][h]%mod) % mod
}
}
}
return f[n][26]
}
```

#### TypeScript

```ts
function keyboard(k: number, n: number): number {
const c: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
c[0][0] = 1;
const mod = 10 ** 9 + 7;
for (let i = 1; i <= n; ++i) {
c[i][0] = 1;
for (let j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
const f: number[][] = Array.from({ length: n + 1 }, () => Array(27).fill(0));
f[0].fill(1);
for (let i = 1; i <= n; ++i) {
for (let j = 1; j < 27; ++j) {
for (let h = 0; h <= Math.min(i, k); ++h) {
const v = Number((BigInt(f[i - h][j - 1]) * BigInt(c[i][h])) % BigInt(mod));
f[i][j] = (f[i][j] + v) % mod;
}
}
}
return f[n][26];
}
```

<!--- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
28 changes: 28 additions & 0 deletions lcp/LCP 25. 古董键盘/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class Solution {
public:
int keyboard(int k, int n) {
int f[n + 1][27];
memset(f, 0, sizeof(f));
for (int j = 0; j < 27; ++j) {
f[0][j] = 1;
}
int c[n + 1][k + 1];
memset(c, 0, sizeof(c));
c[0][0] = 1;
const int mod = 1e9 + 7;
for (int i = 1; i <= n; ++i) {
c[i][0] = 1;
for (int j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < 27; ++j) {
for (int h = 0; h <= min(i, k); ++h) {
f[i][j] = (f[i][j] + 1LL * f[i - h][j - 1] * c[i][h] % mod) % mod;
}
}
}
return f[n][26];
}
};
25 changes: 25 additions & 0 deletions lcp/LCP 25. 古董键盘/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
func keyboard(k int, n int) int {
c := make([][]int, n+1)
for i := range c {
c[i] = make([]int, k+1)
c[i][0] = 1
}
const mod int = 1e9 + 7
for i := 1; i <= n; i++ {
for j := 1; j <= k; j++ {
c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod
}
}
f := make([][27]int, n+1)
for j := range f[0] {
f[0][j] = 1
}
for i := 1; i <= n; i++ {
for j := 1; j < 27; j++ {
for h := 0; h <= min(i, k); h++ {
f[i][j] = (f[i][j] + f[i-h][j-1]*c[i][h]%mod) % mod
}
}
}
return f[n][26]
}
24 changes: 24 additions & 0 deletions lcp/LCP 25. 古董键盘/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class Solution {
public int keyboard(int k, int n) {
int[][] c = new int[n + 1][k + 1];
for (int i = 0; i <= n; ++i) {
c[i][0] = 1;
}
final int mod = (int) 1e9 + 7;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
int[][] f = new int[n + 1][27];
Arrays.fill(f[0], 1);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < 27; ++j) {
for (int h = 0; h <= Math.min(i, k); ++h) {
f[i][j] = (f[i][j] + (int) ((long) f[i - h][j - 1] * c[i][h] % mod)) % mod;
}
}
}
return f[n][26];
}
}
11 changes: 11 additions & 0 deletions lcp/LCP 25. 古董键盘/Solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def keyboard(self, k: int, n: int) -> int:
f = [[0] * 27 for _ in range(n + 1)]
f[0] = [1] * 27
mod = 10**9 + 7
for i in range(1, n + 1):
for j in range(1, 27):
for h in range(min(k, i) + 1):
f[i][j] += f[i - h][j - 1] * comb(i, h)
f[i][j] %= mod
return f[n][26]
22 changes: 22 additions & 0 deletions lcp/LCP 25. 古董键盘/Solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function keyboard(k: number, n: number): number {
const c: number[][] = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
c[0][0] = 1;
const mod = 10 ** 9 + 7;
for (let i = 1; i <= n; ++i) {
c[i][0] = 1;
for (let j = 1; j <= k; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
const f: number[][] = Array.from({ length: n + 1 }, () => Array(27).fill(0));
f[0].fill(1);
for (let i = 1; i <= n; ++i) {
for (let j = 1; j < 27; ++j) {
for (let h = 0; h <= Math.min(i, k); ++h) {
const v = Number((BigInt(f[i - h][j - 1]) * BigInt(c[i][h])) % BigInt(mod));
f[i][j] = (f[i][j] + v) % mod;
}
}
}
return f[n][26];
}
Loading