题目描述

✅ 1041. 困于环中的机器人

image-20260928225454986

image-20260928225454987

image-20260928225454988

题意分析

机器人从原点面朝北方出发,将同一串指令无限重复:G 前进一步,L、R 分别左转、右转 90 度。判断它的全部轨迹是否始终落在某个有限范围内,不要求轨迹本身是圆形。

解法:模拟一轮指令

核心思路

[!blue]

同一串指令从不同朝向开始执行,产生的路径和净位移只会随朝向整体旋转。因此只需模拟一轮,记录净位移 (x, y) 和结束方向 dir,便能判断之后每轮如何变化。

若一轮回到原点,后续每轮仍从原点开始,只是可能换一个方向执行同一条有限路径。朝向只有四种,所以轨迹有界。

若一轮没有回到原点,且结束仍朝北,那么每轮的净位移完全相同。执行 k 轮后的位置为 (k*x, k*y),非零位移不断累积,轨迹无界。

剩下的情况是一轮后朝向改变:若转了 180 度,第二轮净位移与第一轮相反,两轮抵消;若转了 90 或 270 度,连续四轮的净位移两两相反,四轮抵消。此时位置和方向都恢复初始状态,之后只会重复有限的这几轮,所以有界。

因此答案是“一轮回到原点,或者一轮后不再朝北”,两个条件满足任意一个即可。

解题步骤

  1. 用 0、1、2、3 分别表示北、东、南、西,初始化 (x, y) = (0, 0)、dir = 0。
  2. 遇到 G,按 dirs[dir] 更新坐标;遇到 L,令 dir = (dir + 3) % 4;遇到 R,令 dir = (dir + 1) % 4。
  3. 一轮结束后,返回 (x == 0 && y == 0) || dir != 0。

代码实现

class Solution {
    public boolean isRobotBounded(String instructions) {
        int x = 0;
        int y = 0;
        int dir = 0;
        int[][] dirs = {
            {0, 1},
            {1, 0},
            {0, -1},
            {-1, 0},
        };

        for (int i = 0; i < instructions.length(); i++) {
            char c = instructions.charAt(i);

            if (c == 'G') {
                x += dirs[dir][0];
                y += dirs[dir][1];
            } else if (c == 'L') {
                // 左转用加三取模,保持方向下标非负。
                dir = (dir + 3) % 4;
            } else {
                dir = (dir + 1) % 4;
            }
        }

        // 回原点或朝向改变,任一成立即可保证轨迹有界。
        return (x == 0 && y == 0) || dir != 0;
    }
}
func isRobotBounded(instructions string) bool {
    x, y := 0, 0
    dir := 0
    dirs := [][]int{
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0},
    }

    for i := 0; i < len(instructions); i++ {
        c := instructions[i]
        if c == 'G' {
            x += dirs[dir][0]
            y += dirs[dir][1]
        } else if c == 'L' {
            // 左转用加三取模,保持方向下标非负。
            dir = (dir + 3) % 4
        } else {
            dir = (dir + 1) % 4
        }
    }

    // 回原点或朝向改变,任一成立即可保证轨迹有界。
    return (x == 0 && y == 0) || dir != 0
}

复杂度分析

  • 时间复杂度:$O(n)$,其中 n 为指令串长度;只扫描一轮。
  • 空间复杂度:$O(1)$。

关键点总结

[!green]

  • 比较的是整轮净位移与净旋转,不是某一步是否转过弯。
  • 朝向改变时最多四轮恢复位置与方向,因此无需真的无限模拟。

易错点总结

[!yellow]

  • 一轮没回原点不代表无界,朝向改变也能让后续位移抵消。
  • 将两个条件取与,会把只满足其一的有界轨迹排除。
  • 左转直接用方向减一取模,可能出现负下标,应加三再模四。
  • 判断的是整轮结束方向,指令中出现过转弯并不等于最终朝向改变。

相似题目

题目 难度 关联与区别
874. 模拟行走机器人 中等 同样模拟位置与朝向,本题指令无限重复,可由一轮后的位移和朝向判断是否被困。
657. 机器人能否返回原点 简单 回到原点足以被困,但本题一轮不回原点而改变朝向时仍可能有界,不能只检查坐标。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2024/64431411
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!