[LeetCode] 489. Robot Room Cleaner 掃地機器人

 

Given a robot cleaner in a room modeled as a grid.html

Each cell in the grid can be empty or blocked.git

The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it made is 90 degrees.github

When it tries to move into a blocked cell, its bumper sensor detects the obstacle and it stays on the current cell.編程

Design an algorithm to clean the entire room using only the 4 given APIs shown below.數組

interface Robot {
  // returns true if next cell is open and robot moves into the cell.
  // returns false if next cell is obstacle and robot stays on the current cell.
  boolean move();

  // Robot will stay on the same cell after calling turnLeft/turnRight.
  // Each turn will be 90 degrees.
  void turnLeft();
  void turnRight();

  // Clean the current cell.
  void clean();
}

Example:函數

Input:
room = [
  [1,1,1,1,1,0,1,1],
  [1,1,1,1,1,0,1,1],
  [1,0,1,1,1,1,1,1],
  [0,0,0,1,0,0,0,0],
  [1,1,1,1,1,1,1,1]
],
row = 1,
col = 3

Explanation:
All grids in the room are marked by either 0 or 1.
0 means the cell is blocked, while 1 means the cell is accessible.
The robot initially starts at the position of row=1, col=3.
From the top left corner, its position is one row below and three columns right.

Notes:post

  1. The input is only given to initialize the room and the robot's position internally. You must solve this problem "blindfolded". In other words, you must control the robot using only the mentioned 4 APIs, without knowing the room layout and the initial robot's position.
  2. The robot's initial position will always be in an accessible cell.
  3. The initial direction of the robot will be facing up.
  4. All accessible cells are connected, which means the all cells marked as 1 will be accessible by the robot.
  5. Assume all four edges of the grid are all surrounded by wall.

 

這道題就是經典的掃地機器人的題目了,以前常常在地裏看到這道題,終於被 LeetCode 收錄了進來了,也總算是找到了一個好的歸宿了。迴歸題目,給了咱們一個掃地機器人,給了4個 API 函數可供咱們調用,具體實現不用咱們操心,讓咱們實現打掃房間 cleanRoom 函數。給的例子中有房間和起始位置的信息,可是代碼中卻沒有,擺明是不想讓咱們被分心。想一想也是,難道咱們在給掃地機器人編程時,還必需要知道用戶的房間信息麼?固然不可以啦,題目中也說了讓咱們盲目 Blindfolded 一些,因此就盲目的寫吧。既然是掃地,那麼確定要記錄哪些位置已經掃過了,因此確定要記錄位置信息,因爲不知道全局位置,那麼只能用相對位置信息了。初始時就是 (0, 0),而後上下左右加1減1便可。位置信息就放在一個 HashSet 中就能夠了,同時爲了方便,還能夠將二維座標編碼成一個字符串。咱們採用遞歸 DFS 來作,初始化位置爲 (0, 0),而後建一個上下左右的方向數組,使用一個變量 dir 來從中取數。在遞歸函數中,咱們首先對起始位置調用 clean 函數,由於題目中說了起始位置是能到達的,便是爲1的地方。而後就要把起始位置加入 visited。而後咱們循環四次,由於有四個方向,因爲遞歸函數傳進來的 dir 是上一次轉到的方向,那麼此時咱們 dir 加上i,爲了防止越界,對4取餘,就是咱們新的方向了,而後算出新的位置座標 newX 和 newY。此時先要判斷 visited 不含有這個新位置,即新位置沒有訪問過,還要調用 move 函數來肯定新位置是否能夠到達,若這兩個條件都知足的話,咱們就對新位置調用遞歸函數。注意遞歸函數調用完成後,咱們要回到調用以前的狀態,由於這裏的 robot 是帶了引用號的,是全局通用的,因此要回到以前的狀態。回到以前的狀態很簡單,由於這裏的機器人的運做方式是先轉到要前進的方向,才能前進。那麼咱們後退的方法就是,旋轉 180 度,前進一步,再轉回到原來的方向。同理,咱們在按順序試上->右->下->左的時候,每次機器人要向右轉一下,由於 move 函數只能探測前方是否能到達,因此咱們必須讓機器人轉到正確的方向,才能正確的調用 move 函數。若是用過掃地機器人的童鞋應該會有影響,當前方有障礙物的時候,機器人圓盤會先轉個方向,而後再繼續前進,這裏要實現的機制也是相似的,參見代碼以下:this

 

class Solution {
public:
    vector<vector<int>> dirs{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    void cleanRoom(Robot& robot) {
        unordered_set<string> visited;
        helper(robot, 0, 0, 0, visited);
    }
    void helper(Robot& robot, int x, int y, int dir, unordered_set<string>& visited) {
        robot.clean();
        visited.insert(to_string(x) + "-" + to_string(y));
        for (int i = 0; i < 4; ++i) {
            int cur = (i + dir) % 4, newX = x + dirs[cur][0], newY = y + dirs[cur][1];
            if (!visited.count(to_string(newX) + "-" + to_string(newY)) && robot.move()) {
                helper(robot, newX, newY, cur, visited);
                robot.turnRight();
                robot.turnRight();
                robot.move();
                robot.turnLeft();
                robot.turnLeft();
            }
            robot.turnRight();
        }
    }
};

 

Github 同步地址:編碼

https://github.com/grandyang/leetcode/issues/489url

 

相似題目:

Walls and Gates 

 

參考資料:

https://leetcode.com/problems/robot-room-cleaner/

https://leetcode.com/problems/robot-room-cleaner/discuss/153530/9ms-Java-with-Explanations

https://leetcode.com/problems/robot-room-cleaner/discuss/139057/Very-easy-to-understand-Java-solution

https://leetcode.com/problems/robot-room-cleaner/discuss/151942/Java-DFS-Solution-with-Detailed-Explanation-and-6ms-(99)-Solution

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索