LintCode 题解丨大厂真题:骑士的最短路线

简介: LintCode 题解丨大厂真题:骑士的最短路线

给定骑士在棋盘上的 ​初始​ 位置(一个2进制矩阵 ​0​ 表示空 ​1​ 表示有障碍物),找到到达 ​终点​ 的最短路线,返回路线的长度。如果骑士不能到达则返回 ​-1​ 。

起点跟终点必定为空.
骑士不能碰到障碍物.
路径长度指骑士走的步数.
在线评测地址:
LintCode 领扣

说明

如果骑士的位置为 (x,y),他下一步可以到达以下这些位置:

(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)
样例

例1:

输入:
[[0,0,0],
[0,0,0],
[0,0,0]]
source = [2, 0] destination = [2, 2]
输出: 2
解释:
[2,0]->[0,1]->[2,2]
例2:

输入:
[[0,1,0],
[0,0,1],
[0,0,0]]
source = [2, 0] destination = [2, 2]
输出:-1
算法:BFS

朴素​BFS​搜搜最短路,BFS概括来说就是像雷达一样,一层一层进行寻找目标点。当找到目标点后进行回溯。从而找到最佳路径。也就是说每走一步都要找到到达该点的最短的路径,最终得到到达所有点的最短路径,这题每一次的下一步做了规定,按照日字形跳到下一步。

根据下一跳位置建立方向数组
​dx=[1, 1, 2, 2, -1, -1, -2, -2]​
​dy=[2, -2, 1, -1, 2, -2, 1, -1]​
遍历八个方向,进行搜索
用​grid​数组标注是否访问过某点
注意判断下一跳的位置是否越界
复杂度分析

时间复杂度​O(n*m)​
最多跑一边图 n为图的行数,m为图的列数,最多跑一边图,即n*m
空间复杂度​O(n*m)​
所有点的信息 n为图的行数,m为图的列数
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) {
    int n = grid.length,m = grid[0].length;
    if (n == 0 || m == 0) {
        return -1;
    }
    
    int[] dx = {1, 1, 2, 2, -1, -1, -2, -2};
    int[] dy = {2, -2, 1, -1, 2, -2, 1, -1};
    Queue<Point> queue = new LinkedList<>();
    queue.offer(source);
    grid[source.x][source.y] = true;
    int ans = 0;
    
    while (!queue.isEmpty()) {
        int size = queue.size();
        for (int k = 0; k < size; k++) {
            Point cur = queue.poll();
            //到达终点,返回距离
            if (cur.x == destination.x && cur.y == destination.y)  {
                return ans;
            }
            for (int i = 0; i < 8; i++) {
                Point next = new Point (
                    cur.x + dx[i],
                    cur.y + dy[i]
                );
                //判断下一条可否到达
                if (is_in_bound(next,n,m) && grid[next.x][next.y] == false) {
                    queue.offer(next);
                    grid[next.x][next.y] = true;
                }
            }
        }
        ans++;
    }
    return -1;
}
//判断是否越界
private boolean is_in_bound(Point next,int n,int m) {
    return 0 <= next.x && next.x < n && 0 <= next.y && next.y < m;
}

}
更多题解参考:九章算法官网

相关文章
|
5月前
|
存储 算法
力扣经典150题第三十五题:螺旋矩阵
力扣经典150题第三十五题:螺旋矩阵
20 0
|
5月前
|
存储 物联网
【洛谷 P1135】奇怪的电梯 题解(广度优先搜索)
这是一个关于奇怪电梯的编程问题摘要: - 电梯在每层停,且每层有特定数字 $K_i$ 决定上/下按钮的功能。 - 目标是从 $A$ 楼到 $B$ 楼,求最少按键次数,若无法到达则输出 `-1`。 - 输入包括 $N$(楼层数)、$A$(起点)和 $B$(终点),以及每层的 $K_i$ 数字。 - 使用广度优先搜索(BFS)解决,通过队列存储访问过的楼层,避免重复并计算步数。 - 当到达目标楼层时返回步数,队列空时返回 `-1`。
42 0
|
算法
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和
60 1
|
算法
【LeetCode力扣】42. 接雨水
【LeetCode力扣】42. 接雨水
78 0
|
算法 Android开发
LeetCode 周赛上分之旅 #34 按部就班地解决动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
71 0
|
算法 图计算 C++
每日算法系列【LeetCode 42】接雨水
每日算法系列【LeetCode 42】接雨水
115 0
|
算法 C++ Python
每日算法系列【LeetCode 719】找出第 k 小的距离对
每日算法系列【LeetCode 719】找出第 k 小的距离对
LeetCode每日一题——1184. 公交站间的距离
环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。
108 0
LeetCode每日一题——1184. 公交站间的距离
|
机器学习/深度学习 算法
『牛客|每日一题』岛屿数量
基础算法无论在研究生面试还是求职面试都是十分重要的一环,这里推荐一款算法面试神器:牛客网-面试神器;算法题只有多刷勤刷才能保持思路与手感,大家赶紧行动起来吧(温馨提示:常见的面试问答题库也很nice哦 https://www.nowcoder.com/link/pc_csdncpt_ll_sf
120 0
『牛客|每日一题』岛屿数量