@@ -42,4 +42,159 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2025.%20%E5%8F%A4%
42
42
43
43
<!-- solution:start -->
44
44
45
+ ### 方法一:动态规划
46
+
47
+ 我们定义 $f[ i] [ j ] $ 表示按了 $i$ 次按键,且使用了前 $j$ 个字母的方案数。初始时 $f[ 0] $ 全部为 $1$,表示没有按键时只有一种方案,其余 $f[ i] [ j ] = 0$。
48
+
49
+ 对于 $f[ i] [ j ] $,我们考虑其转移方式。我们可以枚举第 $j$ 个字母一共使用了多少次,设为 $h$,其中 $0 \leq h \leq \min(i, k)$,那么我们可以从 $f[ i - h] [ j - 1 ] $ 转移过来,且第 $j$ 个字母可以在 $i$ 次按键中使用 $h$ 次,方案数为 $\binom{i}{h}$。即:
50
+
51
+ $$
52
+ f[i][j] = \sum_{h = 0}^{\min(i, k)} f[i - h][j - 1] \cdot \binom{i}{h}
53
+ $$
54
+
55
+ 最终答案即为 $f[ n] [ 26 ] $。
56
+
57
+ 时间复杂度 $O(n \times k \times |\Sigma|)$,空间复杂度 $O(n \times |\Sigma|)$。其中 $|\Sigma|$ 表示字母表大小。
58
+
59
+ <!-- tabs:start -->
60
+
61
+ #### Python3
62
+
63
+ ``` python
64
+ class Solution :
65
+ def keyboard (self , k : int , n : int ) -> int :
66
+ f = [[0 ] * 27 for _ in range (n + 1 )]
67
+ f[0 ] = [1 ] * 27
68
+ mod = 10 ** 9 + 7
69
+ for i in range (1 , n + 1 ):
70
+ for j in range (1 , 27 ):
71
+ for h in range (min (k, i) + 1 ):
72
+ f[i][j] += f[i - h][j - 1 ] * comb(i, h)
73
+ f[i][j] %= mod
74
+ return f[n][26 ]
75
+ ```
76
+
77
+ #### Java
78
+
79
+ ``` java
80
+ class Solution {
81
+ public int keyboard (int k , int n ) {
82
+ int [][] c = new int [n + 1 ][k + 1 ];
83
+ for (int i = 0 ; i <= n; ++ i) {
84
+ c[i][0 ] = 1 ;
85
+ }
86
+ final int mod = (int ) 1e9 + 7 ;
87
+ for (int i = 1 ; i <= n; ++ i) {
88
+ for (int j = 1 ; j <= k; ++ j) {
89
+ c[i][j] = (c[i - 1 ][j - 1 ] + c[i - 1 ][j]) % mod;
90
+ }
91
+ }
92
+ int [][] f = new int [n + 1 ][27 ];
93
+ Arrays . fill(f[0 ], 1 );
94
+ for (int i = 1 ; i <= n; ++ i) {
95
+ for (int j = 1 ; j < 27 ; ++ j) {
96
+ for (int h = 0 ; h <= Math . min(i, k); ++ h) {
97
+ f[i][j] = (f[i][j] + (int ) ((long ) f[i - h][j - 1 ] * c[i][h] % mod)) % mod;
98
+ }
99
+ }
100
+ }
101
+ return f[n][26 ];
102
+ }
103
+ }
104
+ ```
105
+
106
+ #### C++
107
+
108
+ ``` cpp
109
+ class Solution {
110
+ public:
111
+ int keyboard(int k, int n) {
112
+ int f[ n + 1] [ 27 ] ;
113
+ memset(f, 0, sizeof(f));
114
+ for (int j = 0; j < 27; ++j) {
115
+ f[ 0] [ j ] = 1;
116
+ }
117
+ int c[ n + 1] [ k + 1 ] ;
118
+ memset(c, 0, sizeof(c));
119
+ c[ 0] [ 0 ] = 1;
120
+ const int mod = 1e9 + 7;
121
+ for (int i = 1; i <= n; ++i) {
122
+ c[ i] [ 0 ] = 1;
123
+ for (int j = 1; j <= k; ++j) {
124
+ c[ i] [ j ] = (c[ i - 1] [ j ] + c[ i - 1] [ j - 1 ] ) % mod;
125
+ }
126
+ }
127
+ for (int i = 1; i <= n; ++i) {
128
+ for (int j = 1; j < 27; ++j) {
129
+ for (int h = 0; h <= min(i, k); ++h) {
130
+ f[ i] [ j ] = (f[ i] [ j ] + 1LL * f[ i - h] [ j - 1 ] * c[ i] [ h ] % mod) % mod;
131
+ }
132
+ }
133
+ }
134
+ return f[ n] [ 26 ] ;
135
+ }
136
+ };
137
+ ```
138
+
139
+ #### Go
140
+
141
+ ```go
142
+ func keyboard(k int, n int) int {
143
+ c := make([][]int, n+1)
144
+ for i := range c {
145
+ c[i] = make([]int, k+1)
146
+ c[i][0] = 1
147
+ }
148
+ const mod int = 1e9 + 7
149
+ for i := 1; i <= n; i++ {
150
+ for j := 1; j <= k; j++ {
151
+ c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod
152
+ }
153
+ }
154
+ f := make([][27]int, n+1)
155
+ for j := range f[0] {
156
+ f[0][j] = 1
157
+ }
158
+ for i := 1; i <= n; i++ {
159
+ for j := 1; j < 27; j++ {
160
+ for h := 0; h <= min(i, k); h++ {
161
+ f[i][j] = (f[i][j] + f[i-h][j-1]*c[i][h]%mod) % mod
162
+ }
163
+ }
164
+ }
165
+ return f[n][26]
166
+ }
167
+ ```
168
+
169
+ #### TypeScript
170
+
171
+ ``` ts
172
+ function keyboard(k : number , n : number ): number {
173
+ const c: number [][] = Array .from ({ length: n + 1 }, () => Array (k + 1 ).fill (0 ));
174
+ c [0 ][0 ] = 1 ;
175
+ const mod = 10 ** 9 + 7 ;
176
+ for (let i = 1 ; i <= n ; ++ i ) {
177
+ c [i ][0 ] = 1 ;
178
+ for (let j = 1 ; j <= k ; ++ j ) {
179
+ c [i ][j ] = (c [i - 1 ][j - 1 ] + c [i - 1 ][j ]) % mod ;
180
+ }
181
+ }
182
+ const f: number [][] = Array .from ({ length: n + 1 }, () => Array (27 ).fill (0 ));
183
+ f [0 ].fill (1 );
184
+ for (let i = 1 ; i <= n ; ++ i ) {
185
+ for (let j = 1 ; j < 27 ; ++ j ) {
186
+ for (let h = 0 ; h <= Math .min (i , k ); ++ h ) {
187
+ const v = Number ((BigInt (f [i - h ][j - 1 ]) * BigInt (c [i ][h ])) % BigInt (mod ));
188
+ f [i ][j ] = (f [i ][j ] + v ) % mod ;
189
+ }
190
+ }
191
+ }
192
+ return f [n ][26 ];
193
+ }
194
+ ```
195
+
196
+ <!--- tabs: end -->
197
+
198
+ <!-- solution: end -->
199
+
45
200
<!-- problem: end -->
0 commit comments