LeetCode 模拟行走机器人(图解+蛮力法)

机器人在一个无限大小的网格上行走,从点 (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

\color{blue}思路分析:思路分析:这道题题意比较简单,蛋式涉及到图中点的移动操作,如果不在纸上画一画会比较抽象,所以建议最好在纸上先模拟一下示例的执行过程。
这道题不但涉及到x、y坐标问题,还涉及到转向(东南西北)。方向图如下:
LeetCode 模拟行走机器人(图解+蛮力法)
黑色的表示的是二维坐标轴,绿色的表示的平面四个方向,红色的表示的方向标号。

观察上图会发现两个很巧妙的规律:
如果向右转90°,相当于顺时针旋转90°,也就是红色的标号循环自增1;
如果向左转90°,相当于逆时针旋转90°,也就是红色的标号循环自减1(或者自增3)。

这样就巧妙的解决了转向问题。

class Solution {
public:
    int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
        set<pair<int, int>> obstaclesSet;//把vector容器转换成set容器,这样方便查找障碍物
        //四个方向{x,y}分别代表北、东、南、西(顺时针一圈)
        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        for (const auto &obstacle : obstacles){
            obstaclesSet.insert({obstacle[0], obstacle[1]});
        }
        pair<int, int> nowLoaction = {0, 0};//现在的位置{x,y}
        int mixDis = 0, directionIndex = 0;//初始朝向北,所以方向index = 0
        //模拟执行所有command
        for (auto command : commands){
            if (command == -1){//顺时针转向90°
                directionIndex = (directionIndex + 1) % 4;
            }
            else if (command == -2){//逆时针转向90° == 顺时针转向270°
                directionIndex = (directionIndex + 3) % 4;
            }
            else{
                //否则执行的行走命令,每次都只向当前方向迈出一步,location增量为{x = directions[directionIndex].first,y = directions[directionIndex].second}
                while (--command >= 0 && obstaclesSet.find({nowLoaction.first + directions[directionIndex].first, nowLoaction.second + directions[directionIndex].second}) == obstaclesSet.end()){
                    //如果当前这一个步没有遇到障碍物,则更新当前location
                    nowLoaction.first += directions[directionIndex].first;
                    nowLoaction.second += directions[directionIndex].second;
                }
                //更新原点到机器人的最大欧式距离的平方
                mixDis = max(mixDis, nowLoaction.first * nowLoaction.first + nowLoaction.second * nowLoaction.second);
            }
        }
        return mixDis;
    }
};

LeetCode 模拟行走机器人(图解+蛮力法)

上一篇:PODAM - Java 对象随机数填充器-属性随机赋值 Mock bean


下一篇:JavaScipt-Object-可选链 "?."