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. Web常见漏洞修复建议

    一.SQL注入修复建议 1.过滤危险字符,例如:采用正则表达式匹配union.sleep.and.select.load_file等关键字,如果匹配到则终止运行. 2.使用预编译语句,使用PDO需要注 ...

  2. String.intern() 方法__jdk1.6与jdk1.7/jdk1.8的不同

    1.为什么要使用intern()方法 intern方法设计的初衷是为了重用string对象,节省内存 用代码实例验证下 public class StringInternTest { static f ...

  3. VJTools

    https://mp.weixin.qq.com/s/cwU2rLOuwock048rKBz3ew

  4. 设计模式八: 委派(Delegate)

    简介 委派模式不属于GOF23种设计模式, 主要角色有三种: 抽象任务角色, 委派者角色, 具体任务角色. 实现层面上, 定义一个抽象接口, 它有若干实现类, 他们真正执行业务方法, 这些子类是具体任 ...

  5. 编程入门视频【 Python、PHP、ThinkPHP、Laravel、Mysql、微信小程序】

    免费分享 Python.PHP.ThinkPHP.Laravel.Mysql.微信小程序等学习视频 点击进入搜刮 免费分享 Python.PHP.ThinkPHP.Laravel.Mysql.微信小程 ...

  6. O2O、B2B、C2C(通俗讲解)

    你在地摊买东西,C2C你去超市买东西,B2C超市找经销商进货,B2B超市出租柜台给经销商卖东西,B2B2C你在网上下载个优惠券去KFC消费,O2O 一:O2O 1.概念: O2O即Online To ...

  7. 一个基于angularJS的工资计算器

    先看界面: 其实在ng中最让人印象深刻的就是数据的双向绑定,在html中就完成了很多操作.大概用到的就是控制器视图服务等,没有分模块写控制器,代码如下: <html ng-app = " ...

  8. 往服务器部署thinkphp5代码时要注意 pathinfo的问题

    往服务器部署thinkphp5代码时要注意 pathinfo的问题 如果nginx没有做任何设置 要使用?s=/的方式访问地址 只需要修改3个地方就可以了,亲测成功,看代码有注解 location ~ ...

  9. 【easy】349. Intersection of Two Arrays

    找两个数组的交集(不要多想,考虑啥序列之类的,就是简单的两堆数求交集啊!!!最后去个重就好了) //LeetCode里用到很多现成函数的时候,苦手だな- //这个题的思路是,先sort,把两个vect ...

  10. 帆软报表(finereport)安装/配置

    1.首先是安装帆软报表软件 下载地址:http://www.finereport.com/product/download           激活码注册格账号就有了 2.启动软件,新建连接数据库 点 ...