[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 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索