返回介绍

solution / 0800-0899 / 0874.Walking Robot Simulation / README

发布于 2024-06-17 01:03:33 字数 7296 浏览 0 评论 0 收藏 0

874. 模拟行走机器人

English Version

题目描述

机器人在一个无限大小的 XY 网格平面上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令 commands

  • -2 :向左转 90
  • -1 :向右转 90
  • 1 <= x <= 9 :向前移动 x 个单位长度

在网格上有一些格子被视为障碍物 obstacles 。第 i 个障碍物位于网格点  obstacles[i] = (xi, yi)

机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,并继续执行下一个命令。

返回机器人距离原点的 最大欧式距离平方 。(即,如果距离为 5 ,则返回 25

 

注意:

  • 北方表示 +Y 方向。
  • 东方表示 +X 方向。
  • 南方表示 -Y 方向。
  • 西方表示 -X 方向。
  • 原点 [0,0] 可能会有障碍物。

 

示例 1:

输入:commands = [4,-1,3], obstacles = []
输出:25
解释:
机器人开始位于 (0, 0):
1. 向北移动 4 个单位,到达 (0, 4)
2. 右转
3. 向东移动 3 个单位,到达 (3, 4)
距离原点最远的是 (3, 4) ,距离为 32 + 42 = 25

示例 2:

输入:commands = [4,-1,4,-2,4], obstacles = [[2,4]]
输出:65
解释:机器人开始位于 (0, 0):
1. 向北移动 4 个单位,到达 (0, 4)
2. 右转
3. 向东移动 1 个单位,然后被位于 (2, 4) 的障碍物阻挡,机器人停在 (1, 4)
4. 左转
5. 向北走 4 个单位,到达 (1, 8)
距离原点最远的是 (1, 8) ,距离为 12 + 82 = 65

示例 3:

输入:commands = [6,-1,-1,6], obstacles = []
输出:36
解释:机器人开始位于 (0, 0):
1. 向北移动 6 个单位,到达 (0, 6).
2. 右转
3. 右转
4. 向南移动 6 个单位,到达 (0, 0).
机器人距离原点最远的点是 (0, 6),其距离的平方是 62 = 36 个单位。

提示:

  • 1 <= commands.length <= 104
  • commands[i] 的值可以取 -2-1 或者是范围 [1, 9] 内的一个整数。
  • 0 <= obstacles.length <= 104
  • -3 * 104 <= xi, yi <= 3 * 104
  • 答案保证小于 231

解法

方法一:哈希表 + 模拟

我们定义一个长度为 $5$ 的方向数组 $dirs=[0, 1, 0, -1, 0]$,数组中的相邻两个元素表示一个方向。即 $(dirs[0], dirs[1])$ 表示向北,而 $(dirs[1], dirs[2])$ 表示向东,以此类推。

我们使用一个哈希表 $s$ 来存储所有障碍物的坐标,这样可以在 $O(1)$ 的时间内判断下一步是否会遇到障碍物。

另外,使用两个变量 $x$ 和 $y$ 来表示机器人当前所在的坐标,初始时 $x = y = 0$。变量 $k$ 表示机器人当前的方向,答案变量 $ans$ 表示机器人距离原点的最大欧式距离的平方。

接下来,我们遍历数组 $commands$ 中的每个元素 $c$:

  • 如果 $c = -2$,表示机器人向左转 $90$ 度,即 $k = (k + 3) \bmod 4$;
  • 如果 $c = -1$,表示机器人向右转 $90$ 度,即 $k = (k + 1) \bmod 4$;
  • 否则,表示机器人向前移动 $c$ 个单位长度。我们将机器人当前的方向 $k$ 与方向数组 $dirs$ 结合,即可得到机器人在 $x$ 轴和 $y$ 轴上的增量。我们将 $c$ 个单位长度的增量分别累加到 $x$ 和 $y$ 上,并判断每次移动后的新坐标 $(nx, ny)$ 是否在障碍物的坐标中,如果不在,则更新答案 $ans$,否则停止模拟,进行下一条指令的模拟。

最后返回答案 $ans$ 即可。

时间复杂度 $O(C \times n + m)$,空间复杂度 $O(m)$。其中 $C$ 表示每次可以移动的最大步数,而 $n$ 和 $m$ 分别表示数组 $commands$ 和数组 $obstacles$ 的长度。

class Solution:
  def robotSim(self, commands: List[int], obstacles: List[List[int]]) -> int:
    dirs = (0, 1, 0, -1, 0)
    s = {(x, y) for x, y in obstacles}
    ans = k = 0
    x = y = 0
    for c in commands:
      if c == -2:
        k = (k + 3) % 4
      elif c == -1:
        k = (k + 1) % 4
      else:
        for _ in range(c):
          nx, ny = x + dirs[k], y + dirs[k + 1]
          if (nx, ny) in s:
            break
          x, y = nx, ny
          ans = max(ans, x * x + y * y)
    return ans
class Solution {
  public int robotSim(int[] commands, int[][] obstacles) {
    int[] dirs = {0, 1, 0, -1, 0};
    Set<Integer> s = new HashSet<>(obstacles.length);
    for (var e : obstacles) {
      s.add(f(e[0], e[1]));
    }
    int ans = 0, k = 0;
    int x = 0, y = 0;
    for (int c : commands) {
      if (c == -2) {
        k = (k + 3) % 4;
      } else if (c == -1) {
        k = (k + 1) % 4;
      } else {
        while (c-- > 0) {
          int nx = x + dirs[k], ny = y + dirs[k + 1];
          if (s.contains(f(nx, ny))) {
            break;
          }
          x = nx;
          y = ny;
          ans = Math.max(ans, x * x + y * y);
        }
      }
    }
    return ans;
  }

  private int f(int x, int y) {
    return x * 60010 + y;
  }
}
class Solution {
public:
  int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
    int dirs[5] = {0, 1, 0, -1, 0};
    auto f = [](int x, int y) {
      return x * 60010 + y;
    };
    unordered_set<int> s;
    for (auto& e : obstacles) {
      s.insert(f(e[0], e[1]));
    }
    int ans = 0, k = 0;
    int x = 0, y = 0;
    for (int c : commands) {
      if (c == -2) {
        k = (k + 3) % 4;
      } else if (c == -1) {
        k = (k + 1) % 4;
      } else {
        while (c--) {
          int nx = x + dirs[k], ny = y + dirs[k + 1];
          if (s.count(f(nx, ny))) {
            break;
          }
          x = nx;
          y = ny;
          ans = max(ans, x * x + y * y);
        }
      }
    }
    return ans;
  }
};
func robotSim(commands []int, obstacles [][]int) (ans int) {
  dirs := [5]int{0, 1, 0, -1, 0}
  type pair struct{ x, y int }
  s := map[pair]bool{}
  for _, e := range obstacles {
    s[pair{e[0], e[1]}] = true
  }
  var x, y, k int
  for _, c := range commands {
    if c == -2 {
      k = (k + 3) % 4
    } else if c == -1 {
      k = (k + 1) % 4
    } else {
      for ; c > 0 && !s[pair{x + dirs[k], y + dirs[k+1]}]; c-- {
        x += dirs[k]
        y += dirs[k+1]
        ans = max(ans, x*x+y*y)
      }
    }
  }
  return
}
function robotSim(commands: number[], obstacles: number[][]): number {
  const dirs = [0, 1, 0, -1, 0];
  const s: Set<number> = new Set();
  const f = (x: number, y: number) => x * 60010 + y;
  for (const [x, y] of obstacles) {
    s.add(f(x, y));
  }
  let [ans, x, y, k] = [0, 0, 0, 0];
  for (let c of commands) {
    if (c === -2) {
      k = (k + 3) % 4;
    } else if (c === -1) {
      k = (k + 1) % 4;
    } else {
      while (c-- > 0) {
        const [nx, ny] = [x + dirs[k], y + dirs[k + 1]];
        if (s.has(f(nx, ny))) {
          break;
        }
        [x, y] = [nx, ny];
        ans = Math.max(ans, x * x + y * y);
      }
    }
  }
  return ans;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文