古董键盘
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 57 ms, 内存: 16.7 MB
/*
* 思路:
* 1. 我们可以使用递归和组合的方法来解决这个问题。
* 2. 使用组合计算选择不同字母和不同按键次数的组合数。
* 3. 将所有组合数相加并取模。
*/
import java.util.stream.IntStream;
public class AntiqueKeyboardStream {
private static final int MOD = 1000000007;
public static int countPossibilities(int k, int n) {
return IntStream.rangeClosed(1, 26).map(i -> countCombinations(i, k, n)).reduce(0, (a, b) -> (a + b) % MOD);
}
private static int countCombinations(int letters, int k, int n) {
if (n == 0) return 1;
if (letters == 0) return 0;
return IntStream.rangeClosed(0, Math.min(k, n))
.map(m -> countCombinations(letters - 1, k, n - m))
.reduce(0, (a, b) -> (a + b) % MOD);
}
public static void main(String[] args) {
System.out.println(countPossibilities(1, 1)); // 26
System.out.println(countPossibilities(1, 2)); // 650
}
}
解释
方法:
此题解利用动态规划的方法解决问题。定义 dp(i, j) 为使用前 i 个字母按 j 次所能产生的不同字符串数量。基本思路是,对于每个字母,我们可以选择按 0 次到 k 次(或者直到 j 次,如果 j 较小)。通过组合数 comb(j, l) 来计算在 j 次按键中选 l 个位置按当前字母的方案数,并用剩余的 (i-1) 个字母填充剩下的 (j-l) 次按键。如果用尽所有字母也无法达到 j 次按键,则返回 0。边界情况是,如果 j 为 0(不需要按键),则有一种可能(即空字符串)。
时间复杂度:
O(n * k)
空间复杂度:
O(n)
代码细节讲解
🦆
在动态规划中,如何确保`dp(i, j)`的计算在不同的`i`和`j`之间正确传递?是否需要初始化某些特定的值来确保逻辑的正确性?
▷🦆
请解释当`j == 0`时,为什么`dp(i, j)`的值应该是1?这是否意味着对于所有的`i`,空字符串总是一个有效的组合?
▷🦆
在`if i * k < j`的情况下,返回0的逻辑是什么?为什么当剩余的最大按键次数小于所需的按键次数时,就没有有效的字符串组合?
▷