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;
}

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

相关文章
|
C# 前端开发
WPF - 图形设计器(Diagram Designer)
原文:WPF - 图形设计器(Diagram Designer)   OpenExpressApp计划中包括建模工具,计划是采用MetaEdit+模型来作为元模型,使用codeproject的《WPF Diagram Designer》一系列文章来做为设计器实现参考,本篇介绍一下codeprojcet的这四个文章,推荐给对图形设计器感兴趣的人去看看,通过WPF的模板功能和其他功能可以很方便的设计出图形编辑器。
4213 0
|
并行计算 监控 网络协议
西门子PLC常用的通讯接口和通讯协议有哪些?RS232、RS485、PPI、MPI、Modbus、Profibus、Uss的特点
西门子PLC常用的通讯接口和通讯协议有哪些?RS232、RS485、PPI、MPI、Modbus、Profibus、Uss的特点
西门子PLC常用的通讯接口和通讯协议有哪些?RS232、RS485、PPI、MPI、Modbus、Profibus、Uss的特点
W9
|
运维 关系型数据库 MySQL
轻松管理Linux服务器的5个优秀管理面板
Websoft9 应用管理平台,github 2k star 开源软件,既有200+的优秀开源软件商店,一键安装。又有可视化的Linux管理面板,文件、数据库、ssl证书方便快捷管理。
W9
1883 149
|
API 开发者
HarmonyOS 之 @Require 装饰器自学指南
在 HarmonyOS 应用开发中,组件初始化传参校验是常见难题。本文深入探讨了 `@Require` 装饰器的使用方法,它能在编译阶段严格校验组件构造传参,提升代码健壮性与开发效率。文章涵盖装饰器定义、版本支持、限制条件及典型使用场景(如父子组件传参校验和 `@ComponentV2` 初始化),并通过错误示例分析常见问题。总结中强调了 `@Require` 的重要性,助力开发者编写更稳定高效的代码。适合鸿蒙开发者学习参考!
491 28
HarmonyOS 之 @Require 装饰器自学指南
|
JSON 文字识别 API
如何提取手写票据信息
本文主要讲述在处理票据信息结构化提取任务时,如何结合OCR(光学字符识别)技术和多模态大模型Qwen-VL来提高票据信息提取的准确性和效率。
1538 17
|
存储 安全 芯片
硬盘数据恢复—硬盘电路板损坏的数据恢复方案
硬盘故障: 硬盘电路板损坏。 硬盘电路板损坏的典型表现: 1、硬盘加电无任何反应。 2、硬盘电路芯片等模块损坏或缺失。
733 15
|
缓存 NoSQL Java
高并发场景秒杀抢购超卖Bug实战重现
在电商平台的秒杀活动中,高并发场景下的抢购超卖Bug是一个常见且棘手的问题。一旦处理不当,不仅会引发用户投诉,还会对商家的信誉和利益造成严重损害。本文将详细介绍秒杀抢购超卖Bug的背景历史、业务场景、底层原理以及Java代码实现,旨在帮助开发者更好地理解和解决这一问题。
708 12
|
传感器 监控 前端开发
产品经理-面试自我介绍
面试自我介绍主要包括个人基本信息、教育经历和工作经历。工作经历按时间倒序描述,重点介绍最近的工作内容与项目经验。例如:我叫小宋,毕业于浙江大学,12年B端产品经验,涉及智慧城市、智慧医疗等项目。项目经历中需说明角色、解决问题的能力及团队结构,如智慧城市项目的智能交通管理和能源管理等模块的规划与实施。成功的产品应符合公司商业价值并满足用户核心诉求。
620 3
|
编解码 移动开发 HTML5
简要描述多媒体的格式都有哪些
【10月更文挑战第5天】简要描述多媒体的格式都有哪些。
666 3