Given a knight in a chessboard (a binary matrix with0as empty and1as barrier) with asourceposition, find the shortest path to adestinationposition, return the length of the route.
Return-1if knight can not reached.
Notice
source and destination must be empty.
Knight can not enter the barrier.
Clarification
If the knight is at (x,y), he can get to the following positions in one step:
(x + 1, y + 2)
(x + 1, y - 2)
(x - 1, y + 2)
(x - 1, y - 2)
(x + 2, y + 1)
(x + 2, y - 1)
(x - 2, y + 1)
(x - 2, y - 1)
/**
* Definition for a point.
* public class Point {
* publoc int x, y;
* public Point() { x = 0; y = 0; }
* public Point(int a, int b) { x = a; y = b; }
* }
*/
public int shortestPath(boolean[][] grid, Point source, Point destination) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return -1;
}
int si = source.x;
int sj = source.y;
int di = destination.x;
int dj = destination.y;
int n = grid.length;
int m = grid[0].length;
// in chess, knight can move these 8 ways.
int[] x = {-2, -2, -1, -1, 1, 1, 2, 2};
int[] y = {-1, 1, 2, -2, 2, -2, 1, -1};
int[][] visitedAndDis = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
visitedAndDis[i][j] = Integer.MAX_VALUE;
}
}
Queue<Point> queue = new LinkedList<>();
queue.offer(source);
visitedAndDis[si][sj] = 0;
while (!queue.isEmpty()) {
Point cur = queue.poll();
int curi = cur.x;
int curj = cur.y;
int curDis = visitedAndDis[curi][curj];
for (int k = 0; k < 8; k++) {
int nexti = curi + x[k];
int nextj = curj + y[k];
if (inBound(nexti, nextj, grid) && !grid[nexti][nextj] && curDis + 1 < visitedAndDis[nexti][nextj]) {
visitedAndDis[nexti][nextj] = curDis + 1;
queue.offer(new Point(nexti, nextj));
}
}
}
return visitedAndDis[di][dj] == Integer.MAX_VALUE ? -1 : visitedAndDis[di][dj];
}
private boolean inBound(int row, int col, boolean[][] grid) {
if (row < 0 || col < 0 || row >= grid.length || col >= grid[0].length) {
return false;
}
return true;
}