Given a knight in a chessboard (a binary matrix with 0 as empty and 1 as barrier) with a source position, find the shortest path to a destination position, return the length of the route.
Return -1 if knight can not reached.
Notice
source and destination must be empty.
Knight can not enter the barrier.
Have you met this question in a real interview? Yes
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)
Example
[[0,0,0],
[0,0,0],
[0,0,0]]
source = [2, 0] destination = [2, 2] return 2
[[0,1,0],
[0,0,0],
[0,0,0]]
source = [2, 0] destination = [2, 2] return 6
[[0,1,0],
[0,0,1],
[0,0,0]]
source = [2, 0] destination = [2, 2] return -1
java
/**
* 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 class Solution {
/*
* @param grid: a chessboard included 0 (false) and 1 (true)
* @param source: a point
* @param destination: a point
* @return: the shortest path
*/
int[] dirX = {1, 1, -1, -1, 2, 2, -2, -2};
int[] dirY = {2, -2, 2, -2, 1, -1, 1, -1};
public int shortestPath(boolean[][] grid, Point source, Point destination) {
// write your code here
if(grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return -1;
}
if (source.x == destination.x && source.y == destination.y) {
return 0;
}
Queue<Point> queue = new LinkedList<>();
int count = 0;
queue.offer(source);
while (!queue.isEmpty()) {
int size = queue.size();
count++;
for (int i = 0; i < size; i++) {
Point node = queue.poll();
for (int j = 0; j < 8; j++) {
Point np = new Point(
node.x + dirX[j],
node.y + dirY[j]);
if (inBound(grid, np)) {
grid[np.x][np.y] = true;
if (np.x == destination.x && np.y == destination.y) {
return count;
}
queue.offer(np);
}
}
}
}
return -1;
}
private boolean inBound(boolean[][] grid, Point p) {
int m = grid.length;
int n = grid[0].length;
if (p.x >= 0 && p.x < m && p.y >= 0 && p.y < n) {
return grid[p.x][p.y] == false;
}
return false;
}
}
python
"""
Definition for a point.
class Point:
def __init__(self, a=0, b=0):
self.x = a
self.y = b
"""
import Queue
class Solution:
"""
@param: grid: a chessboard included 0 (false) and 1 (true)
@param: source: a point
@param: destination: a point
@return: the shortest path
"""
def shortestPath(self, grid, source, destination):
# write your code here
if grid is None or len(grid) == 0 or grid[0] is None or len(grid[0]) == 0:
return -1
if source.x == destination.x and source.y == destination.y:
return 0
queue, count = Queue.Queue(), 0
queue.put(source)
dirX = [1, 1, -1, -1, 2, 2, -2, -2]
dirY = [2, -2, 2, -2, 1, -1, 1, -1]
while not queue.empty():
size = queue.qsize()
count += 1
for i in range(size):
node = queue.get()
for j in range(8):
np = Point(node.x + dirX[j],
node.y + dirY[j])
if self.inBound(grid, np):
if np.x == destination.x and np.y == destination.y:
return count
queue.put(np)
grid[np.x][np.y] = True
return -1
def inBound(self, grid, point):
m, n = len(grid), len(grid[0])
if point.x >= 0 and point.x < m and point.y >= 0 and point.y < n:
return grid[point.x][point.y] == False
return False