LeetCode 每日一题笔记
0. 前言
- 日期:2026.04.07
- 题目:2069.模拟行走机器人二
- 难度:中等
- 标签:设计 模拟 数学
1. 题目理解
问题描述 :
给定一个 width x height 的网格,机器人初始位置在 (0, 0),朝向东。机器人按指令前进指定步数,规则如下:
- 沿着当前方向尝试前进一步;
- 若下一步越界,则逆时针转 90 度,再尝试前进一步;
- 完成步数后停止。
需要实现三个方法:
Robot(int width, int height):初始化网格与机器人;void step(int num):前进num步;int[] getPos():返回当前位置[x, y];String getDir():返回当前方向。
示例:
输入:
"Robot", "step", "step", "getPos", "getDir", "step", "step", "step", "getPos", "getDir"
\[6, 3\], \[2\], \[2\], \[\], \[\], \[2\], \[1\], \[4\], \[\], \[\]
输出:
null, null, null, \[4, 0\], "East", null, null, null, \[1, 2\], "West"
2. 解题思路
核心观察
- 机器人只能沿着网格最外围一圈行走,不会进入内部;
- 行走路径是固定环形 ,一圈总步数:
2 × (width-1 + height-1); - 当
num很大时,直接模拟会超时,可先对一圈长度取模,仅需走余数步; - 边界特殊处理:取模后为 0 且回到起点
(0,0)时,方向为南。
算法步骤
- 计算环形周长 :
perimeter = 2 × (width-1 + height-1); - 步数取模优化 :
num %= perimeter,消除重复绕圈; - 边界处理 :若余数为 0 且在起点
(0,0),强制方向为南; - 逐步模拟:按东→北→西→南顺序移动,越界则逆时针转向;
- 实时记录:位置与方向,提供查询接口。
3. 代码实现
java
package com.sheeta1998.lec.lc2069;
public class Robot {
int width = 0;
int height = 0;
int x = 0;
int y = 0;
int direction = 1;//1为东,2为北,3为西,4为南
public Robot(int width, int height) {
this.width = width;
this.height = height;
}
public void step(int num) {
int perimeter = 2 * ((width - 1) + (height - 1));
if (perimeter == 0) return;
if ((num % perimeter) == 0 && x == 0 && y == 0) {
direction = 4;
}
num %= perimeter;
for (int i = 0; i < num; i++) {
if (direction == 1) {
if (x < width - 1) {
x += 1;
} else {
direction += 1;
y += 1;
}
} else if (direction == 2) {
if (y < height - 1) {
y += 1;
} else {
direction += 1;
x -= 1;
}
} else if (direction == 3) {
if (x > 0) {
x -= 1;
} else {
direction += 1;
y -= 1;
}
} else {
if (y > 0) {
y -= 1;
} else {
direction = 1;
x += 1;
}
}
}
}
public int[] getPos() {
int[] res = {x, y};
return res;
}
public String getDir() {
String res;
if (direction == 1) {
res = "East";
} else if (direction == 2) {
res = "North";
} else if (direction == 3) {
res = "West";
} else {
res = "South";
}
return res;
}
}
4. 代码优化说明
优化点1:统一周长计算
将环形周长提取为变量,代码更清晰、不易出错。
优化点2:防 0 宽高崩溃
增加边界判断,避免宽/高为 1 时除零错误。
优化点3:方向映射数组(可选优化)
使用数组映射方向数字与字符串,消除冗长 if-else:
java
private final String[] dirStr = {"East", "North", "West", "South"};
5. 复杂度分析
-
时间复杂度 :O(K)O(K)O(K)
- KKK 为取模后的步数(最大不超过一圈长度);
- 大数取模后,效率极高,避免 O(num)O(num)O(num) 超时。
-
空间复杂度 :O(1)O(1)O(1)
- 仅使用固定变量存储位置、方向、长宽,无额外空间。
6. 总结
- 核心思路:环形路径取模优化 + 边界模拟,解决大数步数超时问题;
- 关键技巧:机器人只在外围行走,路径固定环形,取模后只需模拟余数步;
- 边界重点:回到
(0,0)且步数走完一圈时,方向为南; - 本题考察设计模式、模拟逻辑与数学取模优化,是经典的类设计模拟题。
关键点回顾
- 机器人行走路线是外围环形;
- 大步数必须取模,否则超时;
- 起点
(0,0)满圈后方向为南; - 越界后按东→北→西→南逆时针转向。