当前位置: 首页 > news >正文

【算法题解】24. 模拟机器人行走

这是一道 中等难度 的题

https://leetcode.cn/problems/walking-robot-simulation/description/

题目

机器人在一个无限大小的 XY 网格平面上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令 commands

  • -2 :向左转 90 度
  • -1 :向右转 90 度
  • 1 <= x <= 9 :向前移动 x 个单位长度

在网格上有一些格子被视为障碍物 obstacles 。第 i 个障碍物位于网格点 obstacles[i] = (xi, yi)

机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,但仍然可以继续尝试进行该路线的其余部分。

返回从原点到机器人所有经过的路径点(坐标为整数)的最大欧式距离的平方。(即,如果距离为 5 ,则返回 25

注意:

  • 北表示 +Y 方向。
  • 东表示 +X 方向。
  • 南表示 -Y 方向。
  • 西表示 -X 方向。

示例 1:

输入:commands = [4,-1,3], obstacles = [] 
输出:25 
解释: 机器人开始位于 (0, 0): 1. 向北移动 4 个单位,到达 (0, 4) 2. 右转 3. 向东移动 3 个单位,到达 (3, 4) 距离原点最远的是 (3, 4) ,距离为 32 + 42 = 25

示例 2:

输入:commands = [4,-1,4,-2,4], obstacles = [[2,4]] 
输出:65 
解释:机器人开始位于 (0, 0): 
1. 向北移动 4 个单位,到达 (0, 4) 
2. 右转 
3. 向东移动 1 个单位,然后被位于 (2, 4) 的障碍物阻挡,机器人停在 (1, 4) 
4. 左转 
5. 向北走 4 个单位,到达 (1, 8) 距离原点最远的是 (1, 8) ,距离为 12 + 82 = 65

提示:

  • 1<=commands.length<=1041 <= commands.length <= 10^41<=commands.length<=104
  • commands[i] is one of the values in the list [-2,-1,1,2,3,4,5,6,7,8,9].
  • 0<=obstacles.length<=1040 <= obstacles.length <= 10^40<=obstacles.length<=104
  • −3∗104<=xi,yi<=3∗104-3 * 104 <= xi, yi <= 3 * 10^43104<=xi,yi<=3104
  • 答案保证小于 2312^{31}231

题解思路

这道题理解起来其实很简单,就是求机器人走过的点位当中离原点(0,0)(0,0)(00)最远的点(x,y)(x,y)(xy),并计算其欧式距离的平方。

具体实现逻辑为: 循环遍历命令行数组 commands

  1. 如果遇到 -2-1 就切换机器人方向。
  2. 如果遇到 1 <= x(前进步数) <= 9 按照当前方向一步一步前进。
    • 如果将要前进到的位置(x, y)在给定的障碍物 obstacles 数组中,就停下不能走了,也就是直接退出然后执行下一个命令command
    • 否则每走一步,就计算一下 ans = Math.max(ans, x2 + y2)

示例2 图示

代码实现的难点在于方向的切换,这一类题目我们统一采用 方向数组 来处理。

我们定义当前方向为dir,可取值为 {0,1,2,3} ;分别代表 {北,东,南,西} 。见上图。

那么当机器人遇到改变方向的命令时,我们直接修改dir的值即可:

右转:加一,dir = (dir + 1) % 4。

左转:减一,dir = (dir - 1 + 4) % 4。因为dir - 1可能为负,所以先加4。

然后再分别在xy 两个方向上定义两个方向数组,以Java为例:

int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
  1. 方向为北(0)时:每次前进 x 不变,y 加一。
  2. 方向为东(1)时:每次前进 x 加一,y 不变。
  3. 方向为南(2)时:每次前进 x 不变,y 减一。
  4. 方向为西(3)时:每次前进 x 减一,y 不变。

当遇到行走命令时,每前进一步,其位置变换就应该是(x + dx[dir], y + dy[dir])

另外需要注意的一点是,如果每次判断(x,y)(x, y)(x,y)是不是障碍物点都从 obstaclesobstaclesobstacles 数组找一次的话,那么光查找障碍点的时间复杂度就已经是 O(mn)O(mn)O(mn)了, 其中 mmm 为机器人行走的步数,nnn 为障碍物的个数。我们可以提前以O(n)O(n)O(n)的时间复杂度,将障碍物点初始化到一个哈希表当中,然后我们就可以O(1)O(1)O(1)的时间复杂度来判断一个点是不是障碍物了,具体实现见代码。

代码实现

Java代码实现

class Solution {private Set<Integer> obstacleSet = new HashSet<>();private int factor = 100000;public int robotSim(int[] commands, int[][] obstacles) {genObstacleSet(obstacles);// 当前方向,北:0, 东:1,南:2, 西:3int dir = 0;// 方向数组int[] dx = {0, 1, 0, -1};int[] dy = {1, 0, -1, 0};// 机器人位置int x = 0, y = 0; int ans = 0;for(int command : commands){if(command == -2){dir = (dir + 3) % 4;continue;}if(command == -1){dir = (dir + 1) % 4;continue;}for(int i = 0; i < command; i++){// 如果遇到障碍物,停止在当前位置if(isObstacle(x + dx[dir], y + dy[dir])){break;}x += dx[dir];y += dy[dir];ans = Math.max(ans, x * x + y * y);}}return ans;}// 判断是否是障碍物private boolean isObstacle(int x, int y){return obstacleSet.contains(factor * x + y);}private void genObstacleSet(int[][] obstacles){for(int[] obstacle : obstacles){obstacleSet.add(factor * obstacle[0] + obstacle[1]);}}
}

Go代码实现

func robotSim(commands []int, obstacles [][]int) int {// 初始化障碍点位obstacleMap := make(map[[2]int]bool)for _, obstacle := range obstacles {obstacleMap[[2]int{obstacle[0], obstacle[1]}] = true}// 当前方向dir := 0// 方向数组dx, dy := []int{0, 1, 0, -1}, []int{1, 0, -1, 0}// 当前位置x, y := 0, 0// 答案ans := 0for _, command := range commands {if command == -2 {dir = (dir + 3) % 4continue}if command == -1 {dir = (dir + 1) % 4continue}for i := 0; i < command; i++ {// 遇到障碍物if _, ok := obstacleMap[[2]int{x + dx[dir], y + dy[dir]}]; ok {break;}x += dx[dir]y += dy[dir]ans = max(ans, x * x + y * y)}}return ans}func max(a int, b int) int {if a > b {return a}return b
}

复杂度分析

  • 时间复杂度:O(m+n+k)O(m + n + k)O(m+n+k), 其中 mmm 为机器人行走的步数,nnn 为障碍物的个数,kkk为转换方向的次数。

  • 空间复杂度:O(n)O(n)O(n), nnn 为障碍物的个数。

相关文章:

【算法题解】24. 模拟机器人行走

这是一道 中等难度 的题 https://leetcode.cn/problems/walking-robot-simulation/description/ 题目 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以接收以下三种类型的命令 commands &#xff1a; -2 &am…...

PyTorch 深度学习实战 |用 TensorFlow 训练神经网络

为了更好地理解神经网络如何解决现实世界中的问题&#xff0c;同时也为了熟悉 TensorFlow 的 API&#xff0c;本篇我们将会做一个有关如何训练神经网络的练习&#xff0c;并以此为例&#xff0c;训练一个类似的神经网络。我们即将看到的神经网络&#xff0c;是一个预训练好的用…...

【进阶C语言】静态版通讯录的实现(详细讲解+全部源码)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;正在学习C/C、Java、Python等。 &#x1f4d7;本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等&#xff0…...

【JavaWeb】后端(Maven+SpringBoot+HTTP+Tomcat)

目录一、Maven1.什么是Maven?2.Maven的作用?3.介绍4.安装5.IDEA集成Maven6.IDEA创建Maven项目7.IDEA导入Maven项目8.依赖配置9.依赖传递10.依赖范围11.生命周期二、SpringBoot1.Spring2.SpringBoot3.SpringBootWeb快速入门二、HTTP1.HTTP-概述2.HTTP-请求协议3.HTTP-响应协议…...

面试官:准备了一些springboot相关的面试题,快来看看吧

文章目录摘要Spring Boot 中的注解 RestController 和 Controller 有什么区别&#xff1f;Spring Boot 中如何处理异常&#xff1f;使用 ExceptionHandler 注解处理特定类型的异常&#xff1a;使用 ExceptionHandler 注解可以将特定类型的异常映射到一个处理方法上&#xff0c;…...

原子的波尔模型、能量量子化、光电效应、光谱实验、量子态、角动量

一. 卢瑟福模型 1908年&#xff0c;卢瑟福用α粒子继续轰击金箔&#xff0c;发现有极少数粒子&#xff0c;发生了非常大的偏移。而这对于当时主流的葡萄干面包模型理论分析是相悖的。 原子可看成由带正电的原子核和围绕核运动的一些电子组成&#xff0c;原子中心的原子核带正…...

【如何使用Arduino控制WS2812B可单独寻址的LED】

【如何使用Arduino控制WS2812B可单独寻址的LED】 1. 概述2. WS2812B 发光二极管的工作原理3. Arduino 和 WS2812B LED 示例3.1 例 13.2 例 24. 使用 WS2812B LED 的交互式 LED 咖啡桌4.1 原理图4.2 源代码在本教程中,我们将学习如何使用 Arduino 控制可单独寻址的 RGB LED 或 …...

计算机基本知识扫盲(持续更)

计算机基本知识扫盲Q&#xff1a;硬盘和磁盘有什么区别&#xff1f;A&#xff1a;硬盘和磁盘都是存储数据的设备。磁盘指的是存储数据的圆形或者是方形的光盘&#xff0c;但是硬盘则是指机械式硬盘和固态硬盘。磁盘一般用于存储少量数据&#xff0c;例如软件安装文件、音乐和电…...

学习大数据需要什么语言基础

Python易学&#xff0c;人人都可以掌握&#xff0c;如果零基础入门数据开发行业的小伙伴&#xff0c;可以从Python语言入手。 Python语言简单易懂&#xff0c;适合零基础入门&#xff0c;在编程语言排名上升最快&#xff0c;能完成数据挖掘、机器学习、实时计算在内的各种大数…...

ElasticSearch——详细看看ES集群的启动流程

参考&#xff1a;一起看看ES集群的启动流程 本文主要从流程上介绍整个集群是如何启动的&#xff0c;集群状态如何从Red变成Green&#xff0c;然后分析其他模块的流程。 这里的集群启动过程指集群完全重启时的启动过程&#xff0c;期间要经历选举主节点、主分片、数据恢复等重…...

【教学类-30-01】5以内加法题不重复(一页两份)(包含1以内、2以内、3以内、4以内、5以内加法,抽取最大不重复数量)

作品样式&#xff1a; 背景需求&#xff1a; 虽然学前阶段就对幼儿训练加减法列式题遭到诟病&#xff0c;但是从不少幼儿&#xff08;特别是二胎&#xff09;在家中已经开始适应加减法题型了。 结合中班年龄特点&#xff0c;我从5以内的不重复加法题开始实验&#xff08;雪花…...

写博客8年与人生第一个502万

题记&#xff1a;我们并非生来强大&#xff0c;但依然可以不负青春。 原本想好好写一下如何制定一个目标并通过一点一滴的努力去实现&#xff0c;这三年反思发现其实写自己的经历并不重要。 很多人都听过一句话&#xff1a;榜样的力量是无穷的。 更现实和实际的情况是&#x…...

【华为OD机试真题】日志采集系统(javapython)

日志采集系统 时间限制:1s空间限制:256MB限定语言:不限 题目描述: 日志采集是运维系统的的核心组件。日志是按行生成,每行记做一条,由采集系统分 批上报。 如果上报太频繁,会对服务端造成压力;如果上报太晚,会降低用户的体验;如果一 次上报的条数太多,会导致超时…...

epoll源码剖析

文章目录1.前言2.应用层的体现3.两个重要结构(1)eventpoll(2)epitem4.四个函数(1)epoll_create源码(2)epoll_ctl源码(3)epoll_wait的源码(4)epoll_event_callback()5.水平触发和边缘触发1.状态变化2.LT模式3.ET模式1.前言 好久好久没有更新博客了&#xff0c;最近一直在实习&a…...

Linux驱动开发——高级I/O操作(一)

一个设备除了能通过读写操作来收发数据或返回、保存数据&#xff0c;还应该有很多其他的操作。比如一个串口设备还应该具备波特率获取和设置、帧格式获取和设置的操作;一个LED设备甚至不应该有读写操作&#xff0c;而应该具备点灯和灭灯的操作。硬件设备是如此众多&#xff0c;…...

适配器模式:C++设计模式中的瑞士军刀

适配器模式揭秘&#xff1a;C设计模式中的瑞士军刀引言设计模式的重要性适配器模式简介与应用场景适配器模式在现代软件设计中的地位与价值适配器模式基本概念适配器模式的定义与核心思想类适配器与对象适配器的比较设计原则与适配器模式的关系类适配器实现类适配器模式的UML图…...

【三十天精通Vue 3】 第三天 Vue 3的组件详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 组件的概述1. Vue 3 的组件系统2. Vue 3 组件的特点…...

SqlServer实用系统视图,你了解多少?

SqlServer实用系统视图&#xff0c;你了解多少&#xff1f;前言master..spt_valuessysdatabasessysprocesses一套组合拳sysobjectssys.all_objectssyscolumnssystypessyscommentssysindexes结束语前言 在使用任何数据库软件的时候&#xff0c;该软件都会提供一些可能不是那么公…...

NodeJS Cluster模块基础教程

Cluster简介 默认情况下&#xff0c;Node.js不会利用所有的CPU&#xff0c;即使机器有多个CPU。一旦这个进程崩掉&#xff0c;那么整个 web 服务就崩掉了。 应用部署到多核服务器时&#xff0c;为了充分利用多核 CPU 资源一般启动多个 NodeJS 进程提供服务&#xff0c;这时就…...

[C++笔记]vector

vector vector的说明文档 vector是表示可变大小数组的序列容器(动态顺序表)。就像数组一样&#xff0c;vector也采用连续的存储空间来储存元素。这就意味着可以用下标对vector的元素进行访问&#xff0c;和数组一样高效。与数组不同的是&#xff0c;它的大小可以动态改变——…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...