leetcode
leetcode 751 ~ 800
模拟行走机器人

模拟行走机器人

难度:

标签:

题目描述

代码结果

运行时间: 68 ms, 内存: 20.9 MB


/*
 * Solution for the robot walking problem using Java Stream.
 * The robot starts at the origin (0, 0) facing north. It can receive commands to
 * turn left, turn right, or move forward. The robot must avoid obstacles and
 * find the maximum squared Euclidean distance from the origin.
 *
 * Approach:
 * 1. Define the directions for north, east, south, and west.
 * 2. Use a set to store obstacles for quick lookup.
 * 3. Use Java Stream API to process the commands and update the robot's state.
 */

import java.util.HashSet;
import java.util.Set;
import java.util.stream.IntStream;

public class RobotSimulatorStream {
    public int robotSim(int[] commands, int[][] obstacles) {
        int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        Set<String> obstacleSet = new HashSet<>();
        for (int[] obstacle : obstacles) {
            obstacleSet.add(obstacle[0] + "," + obstacle[1]);
        }

        int[] position = {0, 0};
        int[] dir = {0};
        int[] maxDistSq = {0};

        IntStream.of(commands).forEach(command -> {
            if (command == -1) {
                dir[0] = (dir[0] + 1) % 4;
            } else if (command == -2) {
                dir[0] = (dir[0] + 3) % 4;
            } else {
                IntStream.range(0, command).forEach(i -> {
                    int newX = position[0] + directions[dir[0]][0];
                    int newY = position[1] + directions[dir[0]][1];
                    if (obstacleSet.contains(newX + "," + newY)) {
                        return;
                    }
                    position[0] = newX;
                    position[1] = newY;
                    maxDistSq[0] = Math.max(maxDistSq[0], position[0] * position[0] + position[1] * position[1]);
                });
            }
        });
        return maxDistSq[0];
    }
}

解释

方法:

这个题解首先定义了一个方向数组 dir4,该数组代表了机器人可以朝向的四个方向:北(0,1),东(1,0),南(0,-1),和西(-1,0)。初始时机器人面向北方。题解中还定义了变量 k 来表示机器人当前的方向。对于每个命令,如果命令是 -2 或 -1,这表示机器人需要转向。转向操作通过改变索引 k 来实现,利用模运算确保 k 始终在 0 到 3 的范围内。如果命令是一个正数,机器人则向前移动指定的步数。在移动过程中,题解检查是否碰到障碍物。如果当前方向的下一步位置不是障碍物,则更新机器人的位置;如果是障碍物,则停止移动。每次移动后,题解都会计算并更新机器人离原点的最大欧式距离的平方。

时间复杂度:

O(m)

空间复杂度:

O(o)

代码细节讲解

🦆
如何处理在原点即存在障碍物的情况,是否有特殊的逻辑来处理这种情况?
在题解中,障碍物是通过集合来管理的,初始位置为(0, 0)。如果原点(0, 0)在障碍物集合中,实际上在这种情况下,机器人初始位置仍然设定为原点,并不会受到影响,因为机器人在原点开始并没有移动命令。机器人的移动仅在接收到向前的命令时受到障碍物的影响,而在原点有障碍物不影响机器人的初始状态,但会阻止机器人向该障碍物方向的移动。
🦆
在题解中提到的方向数组dir4是如何确保机器人在接收-2或-1命令后,仍然可以正确并有效地转向的?
方向数组dir4定义了四个元素,分别对应北、东、南、西的方向。当机器人接收到-2命令时,执行左转90度,即方向索引减1;接收到-1命令时,执行右转90度,即方向索引加1。使用模运算(%4)确保索引值始终在0到3之间,即使索引值变为负数或超过3,模运算也能将其正确地映射回0到3的范围内。这样可以保证无论机器人如何转向,都能够根据数组索引准确地获取到相应的方向向量。
🦆
当机器人遇到障碍物时,题解中的策略是停止移动,这是否意味着机器人会在障碍物前停止所有后续命令的执行,还是仅停止当前命令的执行?
当机器人遇到障碍物时,题解中的策略仅是停止当前命令的执行,即机器人停在障碍物前的最后一个位置,而不是停止所有后续命令的执行。机器人在遇到障碍物后,会继续接收并执行后续的命令。这意味着如果后续命令指示机器人转向或向不同方向移动,它仍然可以执行这些命令。
🦆
题解似乎没有提及如果命令数组中包含非法值(例如不在-2, -1, 1-9范围内的命令),应如何处理?
题解中确实没有提及如何处理命令数组中的非法值。在实际应用中,应该在处理命令之前验证每个命令的合法性。可以通过检查每个命令是否为-2, -1, 或是一个正整数。如果发现非法命令,可以选择忽略这些命令、抛出异常、或是停止执行,具体处理方式取决于应用的需求和设计。

相关问题