zoukankan      html  css  js  c++  java
  • lintcode611- Knight Shortest Path- medium

    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.

    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

    public int shortestPath(boolean[][] grid, Point source, Point destination)

    算法:BFS。层级遍历+灌水法。1.推入初始点 2.对queue层级遍历,每层步数计数+1。检查8方向是否有效,推入下一层。(切记每次推的时候都把那一位置标记为BARRIER,以免之后再回到这个点遍历死循环,相当于set功能)3.每层对当前层的点要检查是不是终点,终点就返回步数计数。

    数据结构:Queue (BFS), 灌水法标记替代了本应的set,int size(层级遍历), int[] dx,dy(矩阵遍历)

    细节:关键在于避免回到原点的方法,这里很巧妙用灌水法的思想。

    /**
     * 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 
         */
        
        public int shortestPath(boolean[][] grid, Point source, Point destination) {
            // write your code here
            if (grid == null || grid.length == 0 || grid[0].length == 0) {
                return -1;
            }
            
            int[] dx = {+1, +1, -1, -1, +2, +2, -2, -2};
            int[] dy = {+2, -2, +2, -2, +1, -1, +1, -1};
            
            Queue<Point> queue = new LinkedList<Point>();
            //这里无法创造一个set!!!因为point每次new新的了,不能hash去重!用了虾米一个很巧妙的类似灌水法的方法!!!直接棋盘上堵了路,来避免后续再遍历
            // Set<Point> set = new HashSet<Point>();
            if (isValid(grid, source)) {
                queue.offer(source);
                grid[source.x][source.y] = true;
            }
            
            int steps = 0;
            while (!queue.isEmpty()) {
                int size = queue.size();
                for (int i = 0; i < size; i++) {
                    Point crt = queue.poll();
                    if (isDest(grid, crt, destination)) {
                        return steps;
                    }
                    for (int j = 0; j < 8; j++) {
                        Point next = new Point(crt.x + dx[j], crt.y + dy[j]);
                        if (isValid(grid, next)) {
                            queue.offer(next);
                            //在这里堵死!!重要!!!!!
                            //而且一定写这里,这个作用的都和queue.offer搭配!
                            grid[next.x][next.y] = true;
                        }
                    }
                }
                steps++;
            }
            return -1;
        }
        
        private boolean isValid(boolean[][] grid, Point point) {
            int h = grid.length;
            int w = grid[0].length;
            return point.x >= 0 && point.x < h && point.y >= 0 && point.y < w && !grid[point.x][point.y];
        }
        
        private boolean isDest(boolean[][] grid, Point source, Point destination) {
            return source.x == destination.x && source.y == destination.y;
        }
    }
  • 相关阅读:
    [HDU] 2084 数塔 入门dp
    一些实用的小技术,不定时更新^_^
    上传图片的综合验证
    一个典型web接口处理
    js控制背景音乐播放
    心开始平和起来
    冲突域广播域
    可怜的我的啊~~
    祈祷
    昨夜小楼又东风...
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7749261.html
Copyright © 2011-2022 走看看