该题标签:贪心算法;难度:简单;根据题意,贪的是每个方向最长能走的路。其实也是根据题意,写出的代码
思路:先set存储障碍点,以防重复。然后每个指令进行一次转向或行走判断是否到达障碍点的判断。关于方向,根据顺时针方向定义。其中,最大欧式距离的平方 不等于 最终位置的欧式距离,而是过程中所有的欧式距离的最大值
补充:
欧式距离即直线距离,曼哈顿距离即为到达方式的距离(多个);切比雪夫距离(Chebyshev distance)或是L∞度量是向量空间中的一种度量,二个点之间的距离定义为其各座标数值差的最大值
题目:
- 模拟行走机器人
机器人在一个无限大小的网格上行走,从点 (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
解法:
// 时间 O(n+k) 空间 O(k) n,k分别两数组长度
/**
* @param {number[]} commands
* @param {number[][]} obstacles
* @return {number}
*/
var robotSim = function(commands, obstacles) {
let obstaclesSet = new Set()
for(let i = 0; i < obstacles.length; i++){
obstaclesSet.add(obstacles[i][0] + '_' + obstacles[i][1])
}
let dir = 0, x = 0, y = 0 // 起始位置及方向 0123 -> 北东南西
let dx = [0, 1, 0, -1], dy = [1, 0, -1, 0]; // 各方向唯一距离,得到方向即可计算
let res = 0
for(let i = 0; i < commands.length; i++){
if(commands[i] === -2){ // 向左转90
dir = (dir + 3) % 4
}else if(commands[i] === -1){ // 向右转90
dir = (dir + 1) % 4
}else{
for(let j = 1; j <= commands[i]; j++){
let nx = x + dx[dir], ny = y + dy[dir]
if(!obstaclesSet.has(nx + '_' + ny)){
x = nx
y = ny
res = Math.max(res, x*x + y*y)
}else{
break;
}
}
}
// console.log("x,y,dir", x, y, dir)
}
return res
};