Skip to content

Commit fbfb9b5

Browse files
havanagrawalfishercoder1534
authored andcommitted
Add solution for 935 (#60)
1 parent 5984345 commit fbfb9b5

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Your ideas/fixes/algorithms are more than welcome!
6060
|941|[Valid Mountain Array](https://leetcode.com/problems/valid-mountain-array/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_941.java) | O(n) | O(1) | |Easy|
6161
|938|[Range Sum of BST](https://leetcode.com/problems/range-sum-of-bst/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_938.java) | O(n) | O(n) | |Medium| BST, recursion, DFS
6262
|937|[Reorder Log Files](https://leetcode.com/problems/reorder-log-files/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_937.java) | O(n) | O(n) | |Easy|
63+
|935|[Knight Dialer](https://leetcode.com/problems/knight-dialer/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_935.java) | O(n) | O(1) | |Medium|
6364
|933|[Number of Recent Calls](https://leetcode.com/problems/number-of-recent-calls/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_933.java) | O(n) | O(n) | |Easy|
6465
|929|[Unique Email Addresses](https://leetcode.com/problems/unique-email-addresses/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_929.java) | O(n) | O(n) | |Easy|
6566
|925|[Long Pressed Name](https://leetcode.com/problems/long-pressed-name/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_925.java) | O(n) | O(1) | |Easy|
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.fishercoder.solutions;
2+
3+
/**
4+
* A chess knight can move as indicated in the chess diagram below:
5+
*
6+
* https://assets.leetcode.com/uploads/2018/10/12/knight.png
7+
*
8+
* |---|---|---|
9+
* | 1 | 2 | 3 |
10+
* |---|---|---|
11+
* | 4 | 5 | 6 |
12+
* |---|---|---|
13+
* | 7 | 8 | 9 |
14+
* |---|---|---|
15+
* | x | 0 | x |
16+
* |---|---|---|
17+
*
18+
* This time, we place our chess knight on any numbered key of a phone pad (indicated above), and the knight makes N-1 hops.
19+
* Each hop must be from one key to another numbered key.
20+
*
21+
* 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.
22+
*
23+
* How many distinct numbers can you dial in this manner?
24+
*
25+
* Since the answer may be large, output the answer modulo 10^9 + 7.
26+
*
27+
* Note:
28+
* * 1 <= N <= 5000
29+
*/
30+
31+
public class _935 {
32+
/*
33+
* The intuition is to calculate the number of ways
34+
* we can reach a key k after i hops, based on the number of ways we can reach keys x after i-1 hops
35+
* s.t. the knight can move from x to k in one move
36+
* For example,
37+
* We can reach 6 in 3 ways after 1 hop (1 -> 6, 7 -> 6 or 0 -> 6)
38+
* We can reach 8 in 2 ways after 1 hop (1 -> 8 or 3 -> 8)
39+
* Thus, we can reach 1 in 5 ways after 2 hops:
40+
* . 1. 1 -> 6 -> 1
41+
* . 2. 7 -> 6 -> 1
42+
* . 3. 0 -> 6 -> 1
43+
* 4. 1 -> 8 -> 1
44+
* 5. 3 -> 8 -> 1
45+
*/
46+
public static class Solution1 {
47+
private static final int MOD = 1000_000_007;
48+
49+
// whereFromHere[i] is an array of keys that can be reached from the ith digit
50+
private static final int[][] whereFromHere = {
51+
{4, 6}, {6, 8}, {7, 9}, {4, 8}, // 0, 1, 2, 3
52+
{3, 9, 0}, {}, {1, 7, 0}, // 4, 5, 6
53+
{2, 6}, {1, 3}, {2, 4} // 7, 8, 9
54+
};
55+
56+
public int knightDialer(int N) {
57+
// a[i] is the number of ways we can end up on the ith digit
58+
// The initial array is for N = 1, i.e. for 0 hops.
59+
long[] a = new long[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
60+
61+
// Simulate N - 1 hops
62+
for (int i = 0; i < N - 1; ++i) {
63+
long[] tmp = new long[10];
64+
65+
// For each digit
66+
for (int j = 0; j < 10; j++) {
67+
// Which other digits can we reach?
68+
for (int k : whereFromHere[j]) {
69+
tmp[j] = (tmp[j] + a[k]) % MOD;
70+
}
71+
}
72+
73+
// Sanity checks based on symmetry of the keypad
74+
assert tmp[1] == tmp[3];
75+
assert tmp[4] == tmp[6];
76+
assert tmp[7] == tmp[9];
77+
78+
a = tmp;
79+
}
80+
81+
long ans = 0;
82+
for (long k : a) {
83+
ans = (ans + k) % MOD;
84+
}
85+
86+
return (int) ans;
87+
}
88+
}
89+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.fishercoder;
2+
3+
import com.fishercoder.solutions._935;
4+
import org.junit.BeforeClass;
5+
import org.junit.Test;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
public class _935Test {
10+
private static _935.Solution1 solution1;
11+
12+
@BeforeClass
13+
public static void setup() { solution1 = new _935.Solution1(); }
14+
15+
@Test
16+
public void test1() {
17+
assertEquals(solution1.knightDialer(1), 10);
18+
}
19+
20+
@Test
21+
public void test2() {
22+
assertEquals(solution1.knightDialer(2), 20);
23+
}
24+
25+
@Test
26+
public void test3() {
27+
assertEquals(solution1.knightDialer(3), 46);
28+
}
29+
}

0 commit comments

Comments
 (0)