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

 .           

This time, we place our chess knight on any numbered key of a phone pad (indicated above), and the knight makes N-1 hops.  Each hop must be from one key to another numbered key.

Each time it lands on a key (including the initial placement of the knight), it presses the number of that key, pressing N digits total.

How many distinct numbers can you dial in this manner?

Since the answer may be large, output the answer modulo 10^9 + 7.

Example 1:

Input: 1
Output: 10

Example 2:

Input: 2
Output: 20

Example 3:

Input: 3
Output: 46

Note:

  • 1 <= N <= 5000

Approach #1: DP. [Java]

class Solution {
public int knightDialer(int N) {
int mod = 1000000007;
int[][][] dp = new int[N+1][5][4]; for (int j = 0; j < 4; ++j)
for (int k = 0; k < 3; ++k)
dp[1][j][k] = 1;
dp[1][3][0] = dp[1][3][2] = 0;
int[][] dirs = {{1, 2}, {1, -2}, {2, 1}, {2, -1},
{-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}}; for (int k = 2; k <= N; ++k) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 3; ++j) {
if (i == 3 && j != 1) continue;
for (int d = 0; d < 8; ++d) {
int x_ = i + dirs[d][0];
int y_ = j + dirs[d][1];
if (x_ < 0 || y_ < 0 || x_ >= 4 || y_ >= 3) continue;
dp[k][i][j] = (dp[k][i][j] + dp[k-1][x_][y_]) % mod;
}
}
}
} int ans = 0;
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 3; ++j) {
ans = (ans + dp[N][i][j]) % mod;
// System.out.print(dp[N][i][j] + " ");
}
// System.out.println("ans = " + ans);
} return ans;
}
}

Analysis:

We can define dp[k][i][j] as of ways to dial and the last key is (i, j) after k steps

Note: dp[*][3][0], dp[*][3][2] are always zero for all the steps.

Init: dp[0][i][j] = 1

Transition: dp[k][i][j] = sum(dp[k-1][i+dy][j+dx]) 8 ways of move from last step.

ans = sum(dp[k])

Time complexity: O(kmn) or O(k*12*8) = O(k)

Space complexity: O(kmn) -> O(12 * 8) = O(1)

  

Approach #2: DP. [C++]

class Solution {
public:
int knightDialer(int N) {
vector<vector<int>> dp(4, vector<int>(3, 1));
dp[3][0] = dp[3][2] = 0;
int mod = pow(10, 9) + 7;
vector<pair<int, int>> dirs = {{1, 2}, {1, -2}, {2, 1}, {2, -1},
{-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}};
for (int k = 2; k <= N; ++k) {
vector<vector<int>> temp(4, vector<int>(3, 0));
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 3; ++j) {
if (i == 3 && j != 1) continue;
for (int k = 0; k < 8; ++k) {
int x_ = i + dirs[k].first;
int y_ = j + dirs[k].second;
if (x_ < 0 || y_ < 0 || x_ >= 4 || y_ >= 3) continue;
temp[i][j] = (temp[i][j] + dp[x_][y_]) % mod;
}
}
}
dp.swap(temp);
} int ans = 0;
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 3; ++j) {
ans = (ans + dp[i][j]) % mod;
}
} return ans;
}
};

  

define dp[k][i] as of ways to dial and the last key is i after k steps

init: dp[0][0:10] = 1

translation: dp[k][i] = sum(dp[k-1][j]) that j  can move to i

ans: sum(dp[k])

Time complexity: O(k*10) = O(k)

Space complexity: O(k*10) -> O(10) = O(1).

Reference:

https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-935-knight-dialer/

935. Knight Dialer的更多相关文章

  1. [LeetCode] 935. Knight Dialer 骑士拨号器

    A chess knight can move as indicated in the chess diagram below:  .            This time, we place o ...

  2. LeetCode 935. Knight Dialer

    原题链接在这里:https://leetcode.com/problems/knight-dialer/ 题目: A chess knight can move as indicated in the ...

  3. 【leetcode】935. Knight Dialer

    题目如下: A chess knight can move as indicated in the chess diagram below:  .            This time, we p ...

  4. 【LeetCode】935. Knight Dialer 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划TLE 空间换时间,利用对称性 优化空间复杂 ...

  5. [Swift]LeetCode935. 骑士拨号器 | Knight Dialer

    A chess knight can move as indicated in the chess diagram below:  .            This time, we place o ...

  6. 109th LeetCode Weekly Contest Knight Dialer

    A chess knight can move as indicated in the chess diagram below:  .            This time, we place o ...

  7. leetcode动态规划题目总结

    Hello everyone, I am a Chinese noob programmer. I have practiced questions on leetcode.com for 2 yea ...

  8. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  9. Android之Dialer之紧急号码

    Android之Dialer之紧急号码 e over any other (e.g. supplementary service related) number analysis. a) 112 an ...

随机推荐

  1. IIS 6.0/7.0/7.5、Nginx、Apache 等服务器解析漏洞总结

    IIS 6.0 1.目录解析:/xx.asp/xx.jpg  xx.jpg可替换为任意文本文件(e.g. xx.txt),文本内容为后门代码 IIS6.0 会将 xx.jpg 解析为 asp 文件. ...

  2. Java jdk 8 新特性

    list 统计(求和.最大.最小.平均) 第一种方式 int suma = listUsers.stream().map(e -> e.getAge()).reduce(Integer::sum ...

  3. bluez蓝牙测试工具

    http://blog.csdn.net/talkxin/article/details/50610984

  4. 关于MySQL在内网中使用另一台机器访问的问题

    要在内网中访问另一台机器的MySQL数据库,需要两步操作 一是把运行MySQL的机器的3306端口打开,最好是能限制访问IP保证安全性. 二是更改MySQL账户的访问权限.MySQL的root账户默认 ...

  5. Redis可以作为简单搜索引擎优化查询

    在日常开发中在遇到一些大数据量的查询的时候,其实可以换种思路采用redis事先都缓存起来,然后通过redis里面进行结果集的运算. 原来的做法可能是 查询SQL太复杂,然后将SQL进行拆分成多个子SQ ...

  6. pthread_once 和 pthread_key

    http://blog.csdn.net/rickyguo/article/details/6259410 一次性初始化 有时候我们需要对一些posix变量只进行一次初始化,如线程键(我下面会讲到). ...

  7. Check time of different search methods

    https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...

  8. 557. Reverse Words in a String III

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  9. java实现网站paypal支付功能并且异步修改订单的状态

    java实现网站paypal支付功能并且异步修改订单的状态:步骤如下 第一步:去paypal的官网https://www.paypal.com注册一个个人账号,在创建沙箱测试账号时需要用到 第二步:p ...

  10. 2018.08.30 花园(期望dp)

    题目背景 SCOI2017 DAY2 T1 题目描述 小 A 的花园的长和宽分别是 L,H .小 A 喜欢在花园里做游戏.每次做游戏的时候,他都先把花园均匀分割成 L×H 个小方块,每个方块的长和宽都 ...