LeetCode #935 Knight Dialer 騎士撥號器 935 Knight Dialer 騎士撥號器

935 Knight Dialer 騎士撥號器

Description:
The chess knight has a unique movement, it may move two squares vertically and one square horizontally, or two squares horizontally and one square vertically (with both forming the shape of an L). The possible movements of chess knight are shown in this diagaram:

A chess knight can move as indicated in the chess diagram below:

We have a chess knight and a phone pad as shown below, the knight can only stand on a numeric cell (i.e. blue cell).

Given an integer n, return how many distinct phone numbers of length n we can dial.

You are allowed to place the knight on any numeric cell initially and then you should perform n - 1 jumps to dial a number of length n. All jumps should be valid knight jumps.

As the answer may be very large, return the answer modulo 10^9 + 7.

Example:

Example 1:

Input: n = 1
Output: 10
Explanation: We need to dial a number of length 1, so placing the knight over any numeric cell of the 10 cells is sufficient.

Example 2:

Input: n = 2
Output: 20
Explanation: All the valid number we can dial are [04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]

Example 3:

Input: n = 3
Output: 46

Example 4:

Input: n = 4
Output: 104

Example 5:

Input: n = 3131
Output: 136006598
Explanation: Please take care of the mod.

Constraints:

1 <= n <= 5000

題目描述:
國際象棋中的騎士可以按下圖所示進行移動:


.

這一次,我們將 “騎士” 放在電話撥號盤的任意數字鍵(如上圖所示)上,接下來,騎士將會跳 N-1 步。每一步必須是從一個數字鍵跳到另一個數字鍵。

每當它落在一個鍵上(包括騎士的初始位置),都會撥出鍵所對應的數字,總共按下 N 位數字。

你能用這種方式撥出多少個不同的號碼?

因爲答案可能很大,所以輸出答案模 10^9 + 7。

示例 :

示例 1:

輸入:1
輸出:10

示例 2:

輸入:2
輸出:20

示例 3:

輸入:3
輸出:46

提示:

1 <= N <= 5000

思路:

動態規劃
dp[i][j] 表示到達 i 使用 j 步的方案數
先找到每個按鍵可以到達的位置, 比如 4 出發可以到達 0, 3, 9
所以 dp[4][j] = dp[0][j - 1] + dp[3][j - 1] + dp[9][j - 1]
其他按鍵以此類推
注意 5 只有 n = 1 時能訪問
注意到 dp 每一行只與上一行有關, 可以用滾動數組優化空間複雜度
時間複雜度爲 O(n), 空間複雜度爲 O(1)

代碼:
C++:

class Solution 
{
public:
    int knightDialer(int n) 
    {
        long x0 = 1, x1 = 1, x2 = 1, x3 = 1, x4 = 1, x6 = 1, x7 = 1, x8 = 1, x9 = 1, pre0 = 1, pre1 = 1, pre2 = 1, pre3 = 1, pre4 = 1, pre6 = 1, pre7 = 1, pre8 = 1, pre9 = 1, mod = 1e9 + 7;
        for (int i = 1; i < n; i++)
        {
            x0 = pre4 + pre6;
            x1 = pre6 + pre8;
            x2 = pre7 + pre9;
            x3 = pre4 + pre8;
            x4 = pre0 + pre3 + pre9;
            x6 = pre0 + pre1 + pre7;
            x7 = pre2 + pre6;
            x8 = pre1 + pre3;
            x9 = pre2 + pre4;
            pre0 = x0 % mod;
            pre1 = x1 % mod;
            pre2 = x2 % mod;
            pre3 = x3 % mod;
            pre4 = x4 % mod;
            pre6 = x6 % mod;
            pre7 = x7 % mod;
            pre8 = x8 % mod;
            pre9 = x9 % mod;
        }
        return (x0 + x1 + x2 + x3 + x4 + (n == 1) + x6 + x7 + x8 + x9) % mod;
    }
};

Java:

class Solution {
    public int knightDialer(int n) {
        long x0 = 1, x1 = 1, x2 = 1, x3 = 1, x4 = 1, x6 = 1, x7 = 1, x8 = 1, x9 = 1, pre0 = 1, pre1 = 1, pre2 = 1, pre3 = 1, pre4 = 1, pre6 = 1, pre7 = 1, pre8 = 1, pre9 = 1, mod = 1_000_000_007;
        for (int i = 1; i < n; i++) {
            x0 = pre4 + pre6;
            x1 = pre6 + pre8;
            x2 = pre7 + pre9;
            x3 = pre4 + pre8;
            x4 = pre0 + pre3 + pre9;
            x6 = pre0 + pre1 + pre7;
            x7 = pre2 + pre6;
            x8 = pre1 + pre3;
            x9 = pre2 + pre4;
            pre0 = x0 % mod;
            pre1 = x1 % mod;
            pre2 = x2 % mod;
            pre3 = x3 % mod;
            pre4 = x4 % mod;
            pre6 = x6 % mod;
            pre7 = x7 % mod;
            pre8 = x8 % mod;
            pre9 = x9 % mod;
        }
        return (int)((x0 + x1 + x2 + x3 + x4 + (n == 1 ? 1 : 0) + x6 + x7 + x8 + x9) % mod);
    }
}

Python:

class Solution:
    def knightDialer(self, n: int) -> int:
        x0 = x1 = x2 = x3 = x4 = x6 = x7 = x8 = x9 = 1
        for i in range(1, n):
            x0, x1, x2, x3, x4, x6, x7, x8, x9 = x4 + x6, x6 + x8, x7 + x9, x4 + x8, x0 + x3 + x9, x0 + x1 + x7, x2 + x6, x1 + x3, x2 + x4
        return (x0 + x1 + x2 + x3 + x4 + (n == 1) + x6 + x7 + x8 + x9) % (10 ** 9 + 7)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章