机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令:
第 i 个障碍物位于网格点 (obstacles[i][0], obstacles[i][1])
机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,但仍然可以继续该路线的其余部分。
返回从原点到机器人所有经过的路径点(坐标为整数)的最大欧式距离的平方。
示例 1:
输入: commands = [4,-1,3], obstacles = []
输出: 25
解释: 机器人将会到达 (3, 4)
示例 2:
输入: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
输出: 65
解释: 机器人在左转走到 (1, 8) 之前将被困在 (1, 4) 处
提示:
0 <= commands.length <= 10000
0 <= obstacles.length <= 10000
-30000 <= obstacle[i][0] <= 30000
-30000 <= obstacle[i][1] <= 30000
答案保证小于 2 ^ 31
思路:
这题难点在于如何实现转向和在障碍物面前停止。下面重点讲一下这两块:
障碍物位置信息由是一个二维数组组成,每个单元对应[x,y]信息。这里可以将x+" "+y合并起来放入一个Set中,如果在移动过程中,坐标信息如果在其中,则不再移动,直至遇到转向或者直接遍历结束。
具体可以参看下面代码,整体过程就是模拟行走过程,比较容易理解。
代码:
class Solution {
public int robotSim(int[] commands, int[][] obstacles) {
int[][] directions = {
{
0, 1}, {
1, 0}, {
0, -1}, {
-1, 0}};
// Set of obstacles indexes in the format of : obstacle[0] + " " + obstacle[1]
Set<String> ops = new HashSet<>();
for (int[] obstacle : obstacles) {
ops.add(obstacle[0] + " " + obstacle[1]);
}
int x = 0, y = 0, index = 0, maxDistSquare = 0;
for (int i = 0; i < commands.length; i++) {
if (commands[i] == -2) {
// Turns left
index = (index + 3) % 4;
} else if (commands[i] == -1) {
// Turns right
index = (index + 1) % 4;
} else {
// Moves forward commands[i] steps
int step = 0;
while (step < commands[i]) {
if (ops.contains((x + directions[index][0]) + " " + (y + directions[index][1]))) break;
x += directions[index][0];
y += directions[index][1];
step++;
}
}
maxDistSquare = Math.max(maxDistSquare, x * x + y * y);
}
return maxDistSquare;
}
}
时间复杂度: O(N+K),N、K分别为commands和obstacles的长度。
空间复杂度: O(K)
1、Logical Thinking with Clear Code
2、Java clean solution with explanation and comments
3、图解【模拟行走机器人】
4、【熊猫刷题Python3】模拟,obstacles要存为set防超时(附视频题解)