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{{-, }, {, }, {, }, {, -}};
void cleanRoom(Robot& robot) {
unordered_set<string> visited;
helper(robot, , , , 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 = ; i < ; ++i) {
int cur = (i + dir) % , newX = x + dirs[cur][], newY = y + dirs[cur][];
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/489

类似题目:

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

[LeetCode] Robot Room Cleaner 扫地机器人的更多相关文章

  1. [LeetCode] 489. Robot Room Cleaner 扫地机器人

    Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked. Th ...

  2. 489. Robot Room Cleaner扫地机器人

    [抄题]: Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or block ...

  3. LeetCode - Robot Room Cleaner

    Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked. Th ...

  4. 【BZOJ5318】[JSOI2018]扫地机器人(动态规划)

    [BZOJ5318][JSOI2018]扫地机器人(动态规划) 题面 BZOJ 洛谷 题解 神仙题.不会.... 先考虑如果一个点走向了其下方的点,那么其右侧的点因为要被访问到,所以必定只能从其右上方 ...

  5. Hihocoder 1275 扫地机器人 计算几何

    题意: 有一个房间的形状是多边形,而且每条边都平行于坐标轴,按顺时针给出多边形的顶点坐标 还有一个正方形的扫地机器人,机器人只可以上下左右移动,不可以旋转 问机器人移动的区域能不能覆盖整个房间 分析: ...

  6. Codeforces Round #461 (Div. 2) D. Robot Vacuum Cleaner

    D. Robot Vacuum Cleaner time limit per test 1 second memory limit per test 256 megabytes Problem Des ...

  7. CodeForces - 922D Robot Vacuum Cleaner (贪心)

    Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that Pushok is a ...

  8. Codeforces 922 C - Robot Vacuum Cleaner (贪心、数据结构、sort中的cmp)

    题目链接:点击打开链接 Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that ...

  9. Java实现第十届蓝桥杯JavaC组第十题(试题J)扫地机器人

    扫地机器人 时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分 [问题描述] 小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所 示. 走廊内部署了 K 台扫地机器人 ...

随机推荐

  1. Node.js实战项目学习系列(1) 初识Node.js

    前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...

  2. Elasticsearch High Level Rest Client 发起请求的过程分析

    本文讨论的是JAVA High Level Rest Client向ElasticSearch6.3.2发送请求(index操作.update.delete--)的一个详细过程的理解,主要涉及到Res ...

  3. 关于中国菜刀,如何"切菜"

    介绍 经典标题党,中国菜刀有大牛已经分析过了->传送门(http://blog.csdn.net/p656456564545/article/details/49671829).博主PHP刚接触 ...

  4. linux 只查看目录下文件夹

    只显示目录文件夹 ls -F |grep "/$" 显示 目录权限 ls -al |grep "^d" 只显示文件 ls -al |grep "^-& ...

  5. 推荐安全且匿名的邮箱 ProtonMail -- PGP算法

    ==以前一直以为平时所用的邮箱是绝对安全的,没有深思它的安全性. 然而你要“犯罪”不留任何痕迹的话,呵呵. 国内应该没有类似 ProtonMail 的邮箱,-->去了解一下 ========== ...

  6. webservice访问的几种方式

    今天在对接的客户用到了webservice,最终采用wsimport生成本地代理方式以SDK的形式对接,但是想的完整的总结一下ws的几种调用方式. 发布服务的IP地址是:192.168.125.116 ...

  7. 3D Slicer中文教程(四)—图像分割

    1.数据获取 (1)下载3D Slicer自带的样本数据 (2)选择自由的数据 (3)网上数据库等其他方式下载数据 2.分割工具 Segment Editor是一个用于分割的模块.细分(也称为轮廓)描 ...

  8. 关于简单的安卓APP状态栏设置(类似沉浸式状态栏)

    1.设置为全屏模式: 在所需设置为全屏模式的逻辑的onCreat()方法中加入以下代码即可: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.K ...

  9. Win7 安装bundle

    bundle依赖ruby,因此需要下载并安装一下内容: 1. rubyinstaller 这个是windows专用的ruby安装程序,下载地址是http://rubyinstaller.org/ 2. ...

  10. 基于Python Django开发的一个mock

    最近研究了一下python的django框架, 发现这个框架不比Java spring boot差, mock同样一个接口, 代码量少很多, 维护起来也很方便, 废话不多说,直接上代码 1. 安装dj ...