Knight Shortest Path Lintcode

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 destinationposition, 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.

Clarification

If the knight is at (xy), 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
In this question, we can use bfs to find the shortest path. Each layer is a step. So for each layer, we should iterate every node in this layer and put their neighbors in the queue. We should use size to decide which layer it is instead of a new queue. Because a new queue will occupy to much memory. 
Besides, when the node is visited, we don't need a hashmap to record. Also because the memory issue.
 
/**
 * 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, destination a point
     * @return the shortest path 
     */
    public int shortestPath(boolean[][] grid, Point source, Point destination) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return -1;
        }
        
        Queue<Point> q = new LinkedList<>();
        q.offer(source);
        
        int[] dx = {1, 1, -1, -1, 2, 2, -2, -2};
        int[] dy = {2, -2, 2, -2, 1, -1, 1, -1};
        int count = 0;
        
        while (!q.isEmpty()) {
            int size = q.size();
            for (int k = 0; k < size; k++) {
                Point point = q.poll();
                if (point.x == destination.x && point.y == destination.y) {
                    return count;
                }
                for (int i = 0; i < 8; i++) {
                    int x = point.x + dx[i];
                    int y = point.y + dy[i];
                    Point subP = new Point(x, y);

                    if (isValid(grid, subP) && !grid[x][y]) {
                        q.offer(subP);
                        grid[x][y] = true;
                    }
                }
            }
            count++;
        }
        return -1;
    }
    public boolean isValid(boolean[][] grid, Point p) {
        int x = p.x;
        int y = p.y;
        return x >= 0 && y >= 0 && x < grid.length && y < grid[0].length;
    }
}

Just pay attention to the meaning of the question. Don't misunderstand... 一开始还以为是下象棋蹩马腿不能走呢。。。我也是好笑。。。= =

目前bfs可能还不是很熟,以后回顾一下吧。。。
posted @ 2017-03-05 12:57  璨璨要好好学习  阅读(466)  评论(0编辑  收藏  举报