来源

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/walking-robot-simulation/

描述

机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令:
-2:向左转 90 度
-1:向右转 90 度
1 <= x <= 9:向前移动 x 个单位长度

在网格上有一些格子被视为障碍物。
第 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

题解

  1. class Solution {
  2. public int robotSim(int[] commands, int[][] obstacles) {
  3. int[] dx = new int[]{0, 1, 0, -1};
  4. int[] dy = new int[]{1, 0, -1, 0};
  5. int x = 0, y = 0, di = 0;
  6. // use set to speed up the query
  7. Set<Long> obstacleSet = new HashSet<>();
  8. for (int[] obstacle : obstacles) {
  9. long ox = (long) obstacle[0] + 30000;
  10. long oy = (long) obstacle[1] + 30000;
  11. obstacleSet.add((ox << 16) + oy);
  12. }
  13. int ans = 0;
  14. for (int command : commands) {
  15. if (command == -2) {
  16. di = (di + 3) % 4;
  17. } else if (command == -1) {
  18. di = (di + 1) % 4;
  19. } else {
  20. for (int i = 0; i < command; i++) {
  21. int nx = x + dx[di];
  22. int ny = y + dy[di];
  23. long position = (((long) nx + 30000) << 16) + ((long) ny + 30000);
  24. if (!obstacleSet.contains(position)) {
  25. x = nx;
  26. y = ny;
  27. ans = Math.max(ans, x * x + y * y);
  28. } else {
  29. break;
  30. }
  31. }
  32. }
  33. }
  34. return ans;
  35. }
  36. }

复杂度分析

  • 时间复杂度:模拟行走机器人(Walking Robot Simulation) - 图1,其中模拟行走机器人(Walking Robot Simulation) - 图2, 模拟行走机器人(Walking Robot Simulation) - 图3分别是commands和obstacles的长度。
  • 空间复杂度:模拟行走机器人(Walking Robot Simulation) - 图4,用于存储 obstacleSet 而使用的空间。