1. 程式人生 > >[LeetCode] Robot Room Cleaner 掃地機器人 LeetCode All in One 題目講解彙總(持續更新中...)

[LeetCode] Robot Room Cleaner 掃地機器人 LeetCode All in One 題目講解彙總(持續更新中...)

 

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

Each cell in the grid can be empty or blocked.

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

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:

  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函式。如果用過掃地機器人的童鞋應該會有影響,當前方有障礙物的時候,機器人圓盤會先轉個方向,然後再繼續前進,這裡要實現的機制也是類似的,參見程式碼如下:

 

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();
        }
    }
};

 

類似題目:

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 題目講解彙總(持續更新中...)