关于我的 Leetcode 题目解答,代码前往 Github:https://github.com/chenxiangcyr/leetcode-answers
LeetCode题目:935. Knight Dialer
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.
DP 算法,Golang 实现:
const mod = 1000000007
func knightDialer(n int) int {
// key is the target position, value is the source postion which can jump to target position
jumps := map[int][]int {
-1: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
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},
}
// dp[i][j]: distinct jumps to reach number j after jumps i times
dp := make([][]int, n + 1)
for i := range dp {
dp[i] = make([]int, 10)
for j := range dp[i] {
dp[i][j] = -1
}
}
return solve(n, -1, jumps, &dp)
}
func solve(n int, target int, jumps map[int][]int, dp *[][]int) int{
if n == 0 {
return 1
}
if target != -1 && (*dp)[n][target] != -1 {
return (*dp)[n][target]
}
count := 0
for _, source := range jumps[target] {
count = (count + solve(n - 1, source, jumps, dp)) % mod
}
if target != -1 {
(*dp)[n][target] = count
}
return count
}
LeetCode题目:688. Knight Probability in Chessboard
On an n x n
chessboard, a knight starts at the cell (row, column)
and attempts to make exactly k
moves. The rows and columns are 0-indexed, so the top-left cell is (0, 0)
, and the bottom-right cell is (n - 1, n - 1)
.
A chess knight has eight possible moves it can make, as illustrated below. Each move is two cells in a cardinal direction, then one cell in an orthogonal direction.
Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.
The knight continues moving until it has made exactly k
moves or has moved off the chessboard.
Return the probability that the knight remains on the board after it has stopped moving.
Example 1:
Input: n = 3, k = 2, row = 0, column = 0
Output: 0.06250
Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board.
From each of those positions, there are also two moves that will keep the knight on the board.
The total probability the knight stays on the board is 0.0625.
Example 2:
Input: n = 1, k = 0, row = 0, column = 0
Output: 1.00000
Constraints:
1 <= n <= 25
0 <= k <= 100
0 <= row, column <= n
DP 算法,Golang 实现:
var dir = [8][2]int{{2, -1}, {2, 1}, {-2, -1}, {-2, 1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}}
func compute(N, K, r, c int, dp map[[3]int]float64) float64 {
if r < 0 || c < 0 || r >= N || c >= N {
return 0
}
if K == 0 {
return 1
}
if val, ok := dp[[3]int{K, r, c}]; ok {
return val
}
var out float64
for _, v := range dir {
out += compute(N, K - 1, r + v[0], c + v[1], dp) / 8.0
}
dp[[3]int{K, r, c}] = out
return out
}
func knightProbability(N int, K int, r int, c int) float64 {
dp := make(map[[3]int]float64)
return compute(N, K, r, c, dp)
}
LeetCode题目:1197. Minimum Knight Moves
In an infinite chess board with coordinates from -infinity
to +infinity
, you have a knight at square [0, 0]
.
A knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.
Return the minimum number of steps needed to move the knight to the square [x, y]
. It is guaranteed the answer exists.
Example 1:
Input: x = 2, y = 1
Output: 1
Explanation: [0, 0] → [2, 1]
Example 2:
Input: x = 5, y = 5
Output: 4
Explanation: [0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]
BFS 算法,Java 实现:
class Solution {
public int minKnightMoves(int x, int y) {
x = Math.abs(x);
y = Math.abs(y);
if (x == 0 && y == 0) {
return 0;
}
// BFS
Queue> queue = new LinkedList<>();
Set> visited = new HashSet<>();
queue.offer(new Pair(0, 0));
visited.add(queue.peek());
int[][] dirs = new int[][]{{2, 1}, {-2, 1}, {2, -1},
{-2, -1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}};
int level = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Pair parent = queue.poll();
for (int[] dir : dirs) {
int newX = Math.abs(parent.getKey() + dir[0]);
int newY = Math.abs(parent.getValue() + dir[1]);
if (newX == x && newY == y) {
return level + 1;
}
Pair child = new Pair(newX, newY);
if (!visited.contains(child)) {
visited.add(child);
queue.add(child);
}
}
}
level++;
}
return level;
}
}