@@ -42,4 +42,159 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcp/LCP%2025.%20%E5%8F%A4%
4242
4343<!-- solution:start -->
4444
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+
45200<!-- problem: end -->
0 commit comments