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 中的Session

    ===================================Session 工作原理是什么?===================================因为 http 协议是无状态 ...

  2. 数据结构Java实现03----栈:顺序栈和链式堆栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  3. [物理学与PDEs]第3章习题3电磁场的矢势在 Lorentz 规范下满足的方程

    设 $\phi$ 及 ${\bf A}$ 分别为电磁场的标势及矢势 (见第一章 $\S$ 6). 试证明: 若 $\phi$ 及 ${\bf A}$ 满足条件 $$\bex \phi+\cfrac{1 ...

  4. 大数据基础-2-Hadoop-1环境搭建测试

    Hadoop环境搭建测试 1 安装软件 1.1 规划目录 /opt [root@host2 ~]# cd /opt [root@host2 opt]# mkdir java [root@host2 o ...

  5. HBSX2019 游记

    Day -4 训练戳SX2019 3月训练 ZJOI2019 Day1几天前就考了 T1真考了麻将QwQ 九条可怜的毒瘤真的是业界良心 今天中午才起,要开始调整生物钟了 9012HBOIers群里讨论 ...

  6. LNMP一键包安装后解决MySQL无法远程连接问题

    MySQL/MariaDB无法远程连接,如何开启? 1,没有给root对应的权限 -- @'192.168.1.123'可以替换为@‘%’就可任意ip访问 mysql> GRANT ALL PR ...

  7. iOS -- Effective Objective-C 阅读笔记 (7)

    1: 实现 description 方法 NSlog 在输出自定义的类时, 只输出了 类名 和 对象的内存地址. 要想输出更为有用的信息也很简单, 只需要覆写 description 方法并将描述此对 ...

  8. 在DIV中如何控制字的位置?

    想到实现字体在div中处于上图(右下角)的位置的话,只需在字体样式上面加上这行代码就好了:style='margin-top:120px;height:20px;float:right;text-al ...

  9. 文本框监听事件blur()的简单使用

    场景描述:在做编辑功能的时候,经常要判断编码,或者密码之类的是否已经被使用,以前自己做的时候,经常都是在提交了之后才判断的,到现在,才发现,这样做的用户体验不好,完美一点的做法就是当此文本框失去焦点的 ...

  10. mybatis 查询单个对象,结果集类型一定要明确

    简单介绍:用ssm框架已经有很长时间了,但是似乎从来都没有对于查询单个对象,存在问题的,好像也就是那回事,写完sql就查出来了,也从来都没有认真的想过,为什么会这样,为什么要设置结果集类型 代码: / ...