LeetCode 每日一题笔记 日期:2025.04.06 题目:874. 模拟行走机器人

LeetCode 每日一题笔记

0. 前言

  • 日期:2025.04.06
  • 题目:874. 模拟行走机器人
  • 难度:中等
  • 标签:数组 哈希表 模拟

1. 题目理解

问题描述

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

-2 :向左转 90 度

-1 :向右转 90 度

1 <= x <= 9 :向前移动 x 个单位长度

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

机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,并继续执行下一个命令。

返回机器人距离原点的 最大欧式距离 的 平方 。

注意:

北方表示 +Y 方向。

东方表示 +X 方向。

南方表示 -Y 方向。

西方表示 -X 方向。

原点 [0,0] 可能会有障碍物。

示例

输入:commands = [4,-1,3], obstacles = []

输出:25

解释:

机器人开始位于 (0, 0):

  1. 向北移动 4 个单位,到达 (0, 4)
  2. 右转
  3. 向东移动 3 个单位,到达 (3, 4)
    距离原点最远的是 (3, 4) ,距离为 3² + 4² = 25

2. 解题思路

核心观察

  • 机器人仅有北、东、南、西四个朝向,左转/右转会让朝向循环切换;
  • 移动时必须逐格检查障碍物,遇到障碍物立即停止当前移动指令;
  • 使用哈希集合存储障碍物坐标,可实现O(1)时间复杂度的障碍物查询;
  • 只需记录过程中的最大距离平方,无需计算实际欧式距离。

算法步骤

  1. 障碍物预处理:将所有障碍物坐标存入哈希集合,方便快速判断;
  2. 初始化参数:起始坐标(0,0)、初始朝向北方、最大距离平方为0;
  3. 遍历执行命令
    • 转向命令:调整机器人的朝向状态;
    • 移动命令:按照当前朝向逐格移动,每一步校验是否存在障碍物,无障碍物则更新坐标,同步更新最大距离平方;
  4. 返回结果:遍历完所有命令后,输出最大距离平方。

3. 代码实现

java 复制代码
package com.sheeta1998.lec.lc874;

import java.util.HashSet;
import java.util.Set;

class Solution {

    public void setAdd(Set<String> set, int a, int b) {
        String ad = a + "," + b;
        set.add(ad);
    }

    public boolean setCompare(Set<String> set, int a, int b) {
        String cp = a + "," + b;
        return !set.contains(cp);
    }


    public int robotSim(int[] commands, int[][] obstacles) {
        int res = 0;
        int sta = 1;// 1 北,2东,3南,4西
        int x = 0;
        int y = 0;
        Set<String> set = new HashSet<>();
        for (int i = 0; i < obstacles.length; i++) {
            setAdd(set, obstacles[i][0], obstacles[i][1]);
        }
        for (int i = 0; i < commands.length; i++) {

            int a = commands[i];
            if (a < 0) {
                if (a == -1) {
                    if (sta != 4) {
                        sta += 1;
                    } else {
                        sta = 1;
                    }
                } else {
                    if (sta != 1) {
                        sta -= 1;
                    } else {
                        sta = 4;
                    }
                }
            } else {
                if (sta == 1) {
                    for (int j = 0; j < a; j++) {
                        if (!setCompare(set, x, y + 1)) {
                            break;
                        } else {
                            y++;
                        }

                    }
                    res= Math.max(res,x*x+y*y);
                } else if (sta == 2) {
                    for (int j = 0; j < a; j++) {
                        if (!setCompare(set, x + 1, y)) {
                            break;
                        } else {
                            x++;
                        }

                    }
                    res= Math.max(res,x*x+y*y);
                } else if (sta == 3) {
                    for (int j = 0; j < a; j++) {
                        if (!setCompare(set, x, y - 1)) {
                            break;
                        } else {
                            y--;
                        }

                    }
                    res= Math.max(res,x*x+y*y);
                } else {
                    for (int j = 0; j < a; j++) {
                        if (!setCompare(set, x - 1, y)) {
                            break;
                        } else {
                            x--;
                        }

                    }
                   res= Math.max(res,x*x+y*y);
                }
            }

        }

        return res;
    }
}

4. 代码优化说明

优化点1:方向简化

使用二维数组存储四个方向的坐标增量,替代数字状态判断,大幅简化代码逻辑:

java 复制代码
int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}}; // 北、东、南、西
int d = 0; // 方向索引

优化点2:障碍物存储优化

使用Long类型替代字符串存储坐标,减少字符串拼接开销,查询效率更高:

java 复制代码
Set<Long> set = new HashSet<>();
long code = ((long)x << 32) | (y & 0xFFFFFFFFL);

优化点3:精简重复逻辑

合并最大距离更新的代码,消除冗余逻辑。

5. 复杂度分析

  • 时间复杂度 :O(M+N×K)O(M + N \times K)O(M+N×K)

    • MMM 为障碍物数量,预处理障碍物耗时 O(M)O(M)O(M);
    • NNN 为命令数量,KKK 为单次移动的最大步数(9),移动操作总耗时 O(N×K)O(N \times K)O(N×K);
    • 障碍物查询为 O(1)O(1)O(1) 操作。
  • 空间复杂度 :O(M)O(M)O(M)

    • 哈希集合存储障碍物坐标,空间大小与障碍物数量成正比。

6. 总结

  • 核心思路是模拟机器人行走 + 哈希表快速查障,严格按照题目规则逐命令执行、逐格移动校验;
  • 关键技巧:通过状态标记管理机器人朝向,利用哈希集合解决障碍物查询的效率问题;
  • 本题重点考察模拟能力和哈希表的实际应用,无需复杂算法,重点在于逻辑严谨性。

关键点回顾

  1. 机器人四个朝向循环切换,转向逻辑需处理边界(如北左转→西);
  2. 移动必须逐格判断,遇到障碍物立即终止当前移动指令;
  3. 哈希表是解决障碍物快速查询的最优方案。
相关推荐
Upsy-Daisy8 小时前
AI Agent 项目学习笔记(二):Spring AI 与 ChatClient 主链路解析
人工智能·笔记·学习
杨浦老苏9 小时前
AI原生笔记应用Tolaria
笔记·ai·markdown·obsidian
中屹指纹浏览器10 小时前
浏览器网络栈隔离技术研究:TCP/IP底层指纹生成与规避原理
经验分享·笔记
sulikey10 小时前
个人Linux操作系统学习笔记2 - gcc与库的理解
linux·笔记·学习·操作系统·gcc·
愚昧之山绝望之谷开悟之坡12 小时前
什么是Linter?什么是沙箱!
linux·笔记
菜鸡儿齐12 小时前
编程范式学习笔记
笔记·学习
圣保罗的大教堂12 小时前
leetcode 796. 旋转字符串 简单
leetcode
可依软件crf28612 小时前
推荐一款特别的笔记软件:星轨笔记。普通用户免费功能也基本够用了,我已经免费使用几个月了。
笔记
三品吉他手会点灯12 小时前
C语言学习笔记 - 35.数据类型 - printf函数的非输出控制符与格式优化
c语言·开发语言·笔记·学习
sakiko_13 小时前
Swift学习笔记28-缓存
笔记·学习·swift