935. 骑士拨号器
题目描述
象棋骑士有一个独特的移动方式,它可以垂直移动两个方格,水平移动一个方格,或者水平移动两个方格,垂直移动一个方格(两者都形成一个 L 的形状)。
象棋骑士可能的移动方式如下图所示:
我们有一个象棋骑士和一个电话垫,如下所示,骑士只能站在一个数字单元格上(即蓝色单元格)。
给定一个整数 n,返回我们可以拨多少个长度为 n 的不同电话号码。
你可以将骑士放置在任何数字单元格上,然后你应该执行 n - 1 次移动来获得长度为 n 的号码。所有的跳跃应该是有效的骑士跳跃。
因为答案可能很大,所以输出答案模 109 + 7
.
示例 1:
输入:n = 1 输出:10 解释:我们需要拨一个长度为1的数字,所以把骑士放在10个单元格中的任何一个数字单元格上都能满足条件。
示例 2:
输入:n = 2 输出:20 解释:我们可以拨打的所有有效号码为[04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]
示例 3:
输入:n = 3131 输出:136006598 解释:注意取模
提示:
1 <= n <= 5000
解法
方法一:递推
根据题目描述,我们需要计算出长度为 $n$ 的不同电话号码的数量。其中,每个数字的上一个数字只有固定的几个,我们可以列出每个数字的上一个数字:
当前数字 | 上一个数字 |
---|---|
0 | 4, 6 |
1 | 6, 8 |
2 | 7, 9 |
3 | 4, 8 |
4 | 0, 3, 9 |
5 | |
6 | 0, 1, 7 |
7 | 2, 6 |
8 | 1, 3 |
9 | 2, 4 |
我们可以通过递推的方式,计算出长度为 $n$ 的不同电话号码的数量。设 $f[i]$ 表示长度为 $i$ 的不同电话号码的数量,初始时 $f[1] = 1$。对于长度为 $i$ 的电话号码,我们可以通过长度为 $i - 1$ 的电话号码计算出来,因此我们可以得到递推关系:
$$ \begin{aligned} g[0] & = f[4] + f[6] \ g[1] & = f[6] + f[8] \ g[2] & = f[7] + f[9] \ g[3] & = f[4] + f[8] \ g[4] & = f[0] + f[3] + f[9] \ g[6] & = f[0] + f[1] + f[7] \ g[7] & = f[2] + f[6] \ g[8] & = f[1] + f[3] \ g[9] & = f[2] + f[4] \end{aligned} $$
然后,我们将 $f$ 更新为 $g$,继续计算下一个长度的电话号码,直到计算出长度为 $n$ 的电话号码的数量。
最后,我们将 $f$ 中所有元素相加,取模 $10^9 + 7$,即为答案。
时间复杂度 $O(n)$,其中 $n$ 为电话号码的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 为数字集合,本题中 $|\Sigma| = 10$。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
方法二:矩阵快速幂加速递推
我们假设 $T(n)$ 表示一个 $1 \times 10$ 的矩阵 $\begin{bmatrix} F_0 & F_1 & F_2 \cdots F_9 \end{bmatrix}$,其中 $F_i$ 表示第 $i$ 个电话号码的数量。我们希望根据 $T(n - 1)$ 推出 $T(n)$。也即是说,我们需要一个矩阵 $\textit{base}$,使得 $T(n - 1) \times \textit{base} = T(n)$,即:
$$ \begin{bmatrix} F_0 & F_1 & F_2 \cdots F_9 \end{bmatrix} \times \textit{base} = \begin{bmatrix} F_0' & F_1' & F_2' \cdots F_9' \end{bmatrix} $$
由于 $F_i' = \sum_{j} F_j$,其中 $j$ 是 $i$ 的上一个数字,所以矩阵 $\textit{base}$ 的第 $1$ 列为:
$$ \begin{bmatrix} 0 \ 0 \ 0 \ 0 \ 1 \ 0 \ 1 \ 0 \ 0 \ 0 \end{bmatrix} $$
依次类推,我们可以得到矩阵 $\textit{base}$ 如下:
$$ \begin{bmatrix} 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 \ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \ 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 \ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \ 1 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \ 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \ 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \ 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \end{bmatrix} $$
我们定义初始矩阵 $res = \begin{bmatrix} 1 & 1 & 1 \cdots 1 \end{bmatrix}$,与 $n - 1$ 个 $\textit{base}$ 矩阵相乘,即可得到 $T(n)$。最后,我们将 $T(n)$ 中所有元素相加,取模 $10^9 + 7$,即为答案。求 $\textit{base}^{n - 1}$,可以通过矩阵快速幂的方式,时间复杂度为 $O(\log n)$。
时间复杂度 $O(\log n)$,空间复杂度 $O(|\Sigma|^2)$,其中 $\Sigma$ 为数字集合,本题中 $|\Sigma| = 10$。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|