A robot on an infinite grid starts at point (0, 0) and faces north. The robot can receive one of three possible types of commands:html
-2
: turn left 90 degrees-1
: turn right 90 degrees1 <= x <= 9
: move forward x
unitsSome of the grid squares are obstacles. git
The i
-th obstacle is at grid point (obstacles[i][0], obstacles[i][1])
github
If the robot would try to move onto them, the robot stays on the previous grid square instead (but still continues following the rest of the route.)數組
Return the square of the maximum Euclidean distance that the robot will be from the origin.less
Example 1:ide
Input: commands = [4,-1,3], obstacles = [] Output: 25 Explanation: robot will go to (3, 4)
Example 2:idea
Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]] Output: 65 Explanation: robot will be stuck at (1, 4) before turning left and going to (1, 8)
Note:rest
0 <= commands.length <= 10000
0 <= obstacles.length <= 10000
-30000 <= obstacle[i][0] <= 30000
-30000 <= obstacle[i][1] <= 30000
2 ^ 31
.
這道題說在一個無限大的方格中,原點位置有一個面朝北方的機器人,能夠接受三種不一樣的指令,-2 表示左轉 90 度,-1 表示右轉 90 度,正數表示沿當前方向前進該正數步,而後給了一個障礙數組,就是機器人沒法經過的地方,好比當前機器人面前有個障礙物,此時機器人接到的指令是前進x步,可是因爲障礙物的因素,該指令沒法執行,機器人呆在原地不動。只有接到轉向的命令,纔有可能離開當前位置。好,理解了題意以後,來思考如何解題,說到底仍是一道迷宮遍歷的題目,可是跟以往不一樣的是,這裏咱們並不知道迷宮的大小,並且也沒有目標點須要到達,惟一須要作的就是執行指令,當指令執行完了以後,搜索也就中止了,須要找出的是機器人能到達的距離原點最遠的距離。首先對於障礙物,因爲確定要常常的查找下一個位置是否有障礙物,那麼就用一個 HashSet 將全部的障礙物位置存進去,因爲座標是二維的,能夠進行降維處理,以前咱們都是進行 i*n+j 的降維處理,這裏因爲不知道迷宮的大小,因此只能換一種方式,能夠將橫縱座標都轉爲字符串,而後在中間加個短橫杆隔開,這樣就能夠把二維座標變爲一個字符串,放到 HashSet 中了。而後就是處理全部的命令了,在傳統的迷宮遍歷中,使用了方向數組,來控制遍歷的方向,這裏也是一樣須要的,但稍有不一樣的是,這裏方向的順序也有講究,由於機器人的初始狀態是朝北的,因此方向數組的第一個應該是朝北走,上北下南左西右東,這樣方向數組的順序應該是上右下左。用一個變量 idx 來表示方向數組中的當前座標,那麼當遇到 -1,即右轉時,idx 自增1便可,爲了防止越界,須要對4取餘。同理,當遇到 -2,即左轉時,idx 自減1便可,一樣爲了防止越界,先加4,再對4取餘。當遇到正數命令時,此時就該前進了,用兩個變量x和y分別表示當前位置的橫縱座標,均初始化爲0,分別加上方向數組中對應位置的值,就是下一個位置的座標了,在經典的迷宮遍歷問題中,咱們都會檢驗新位置是否越界,以及是否訪問過,而這裏不存在越界的問題,訪沒訪問過也無所謂,重要是看有沒有障礙物,到 HashSet 中去查找一下,若沒有障礙物,則能夠到達,更新x和y爲新的位置,繼續 while 循環便可。當每一個命令執行完了以後,都用當前的x和y距離原點的距離更新一個結果 res 便可,參見代碼以下:code
解法一:htm
class Solution { public: int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) { int res = 0, x = 0, y = 0, idx = 0; unordered_set<string> obs; for (auto a : obstacles) obs.insert(to_string(a[0]) + "-" + to_string(a[1])); vector<int> dirX{0, 1, 0, -1}, dirY{1, 0, -1, 0}; for (int command : commands) { if (command == -1) idx = (idx + 1) % 4; else if (command == -2) idx = (idx - 1 + 4) % 4; else { while (command-- > 0 && !obs.count(to_string(x + dirX[idx]) + "-" + to_string(y + dirY[idx]))) { x += dirX[idx]; y += dirY[idx]; } } res = max(res, x * x + y * y); } return res; } };
下面這種解法跟上面沒有什麼區別,就是集合的保存類型稍有不一樣,上面的解法中咱們對二維座標壓縮成了字符串,這裏直接用個 pair 對兒來保存橫縱座標,須要注意的是,使用 pair 對兒的話就不能用 HashSet 了,只能用 TreeSet,其他地方基本不變,參見代碼以下:
解法二:
class Solution { public: int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) { int res = 0, x = 0, y = 0, idx = 0; set<pair<int, int>> obs; for (auto a : obstacles) obs.insert({a[0], a[1]}); vector<int> dirX{0, 1, 0, -1}, dirY{1, 0, -1, 0}; for (int command : commands) { if (command == -1) idx = (idx + 1) % 4; else if (command == -2) idx = (idx - 1 + 4) % 4; else { while (command-- > 0 && !obs.count({x + dirX[idx], y + dirY[idx]})) { x += dirX[idx]; y += dirY[idx]; } } res = max(res, x * x + y * y); } return res; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/874
相似題目:
參考資料:
https://leetcode.com/problems/walking-robot-simulation/
https://leetcode.com/problems/walking-robot-simulation/discuss/152322/Maximum!-This-is-crazy!