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. 哈希表是解决障碍物快速查询的最优方案。
相关推荐
XiYang-DING2 小时前
【LeetCode】232. 用栈实现队列
算法·leetcode·职场和发展
人道领域2 小时前
【LeetCode刷题日记】142.环形链表Ⅱ
算法·leetcode·链表
oi..2 小时前
Linux入门(2)
linux·笔记·测试工具·安全·网络安全
xwz小王子2 小时前
Nature Communications从结构到功能:基于Kresling折纸的多模态微型机器人设计
人工智能·算法·机器人
一颗小树x2 小时前
《VLA 系列》Humanoid Everyday | 人形机器人 | 开源数据集
机器人·开源数据集·人形机器人·vlm
盘古开天16662 小时前
从 DQN 到机器人导航:用深度 Q 网络让小车学会自己走路(含 PyTorch 代码)
人工智能·pytorch·机器人
Evand J2 小时前
PSINS工具箱笔记——SINS/GNSS的例程
笔记·gnss·组合导航·工具箱·psins·导航工具箱·sins
倦王3 小时前
力扣日刷45
算法·leetcode·职场和发展
阿Y加油吧3 小时前
回溯算法双杀:子集 + 电话号码的字母组合 | 经典模板题解析
算法·leetcode