leetcode
leetcode 751 ~ 800
扫地机器人

扫地机器人

难度:

标签:

题目描述

代码结果

运行时间: 39 ms, 内存: 16.9 MB


/*
 * 思路:
 * 1. 扫地机器人可以在一个网格中移动,并且可以向上、向下、向左、向右移动。
 * 2. 我们使用Java Stream API来处理机器人移动和清洁逻辑。
 * 3. 使用递归和Stream的组合来进行深度优先搜索(DFS)。
 */
import java.util.*;
import java.util.stream.*;

public class Solution {
    private static final int[][] DIRECTIONS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public void cleanRoom(Robot robot) {
        Set<String> visited = new HashSet<>();
        dfs(robot, 0, 0, 0, visited);
    }

    private void dfs(Robot robot, int row, int col, int d, Set<String> visited) {
        String position = row + "," + col;
        if (visited.contains(position)) {
            return;
        }

        visited.add(position);
        robot.clean();

        IntStream.range(0, 4).forEach(i -> {
            int newD = (d + i) % 4;
            int newRow = row + DIRECTIONS[newD][0];
            int newCol = col + DIRECTIONS[newD][1];
            if (robot.move()) {
                dfs(robot, newRow, newCol, newD, visited);
                robot.turnRight();
                robot.turnRight();
                robot.move();
                robot.turnRight();
                robot.turnRight();
            }
            robot.turnRight();
        });
    }
}

解释

方法:

这个题解使用深度优先搜索 (DFS) 的方式来遍历并清扫房间。机器人从初始位置 (0, 0) 开始,朝向初始方向。在每个位置,机器人先清扫当前格子,然后依次尝试向右转并前进到下一个格子,重复 DFS 过程。如果四个方向都无法前进(可能是因为已经清扫过或者被障碍物阻挡),则返回上一个位置。通过递归的方式,机器人能够遍历整个房间的所有可达格子。

时间复杂度:

O(m * n)

空间复杂度:

O(m * n)

代码细节讲解

🦆
在题解中提到的DFS算法中,如何判断'四个方向都无法前进'的具体条件?
在题解中,判断四个方向都无法前进的条件是基于每次尝试移动到新格子时的结果。对于每个方向,机器人首先尝试向该方向移动(robot.move())。如果移动成功,说明该方向可以前进,并且机器人将继续递归调用dfs函数来继续清扫新的格子。如果robot.move()返回False,这意味着这个方向有障碍物或者是已经清扫过的格子边界。当四个方向的robot.move()都返回False时,说明四个方向都无法前进。
🦆
题解提到使用递归的方式实现DFS,这种实现方式是否可能导致栈溢出,尤其是在非常大的房间中?
是的,使用递归方式实现DFS在非常大的房间中可能会导致栈溢出,因为递归的深度可能会非常深,尤其是在房间复杂或者房间尺寸非常大时。每一层的递归调用都会占用调用栈上的空间,如果递归层数过多,将超出栈的容量限制。在实际应用中,可以考虑使用迭代版本的DFS或其他避免深层递归的策略,例如使用显式的栈来管理状态。
🦆
题解中提到'对于每个可达的格子,机器人需要访问一次',那么在算法中如何确保不会重复清扫同一个格子?
在算法中,使用一个集合(set)来存储已经访问过的格子的坐标。在每次清扫一个新的格子之前,会先检查这个格子的坐标是否已经存在于集合中。如果不存在,机器人会清扫这个格子,并将其坐标添加到集合中。这样可以确保每个格子只被访问和清扫一次,防止重复清扫。
🦆
在题解的递归函数dfs中,每次机器人向右转并尝试新的方向后,是否需要再次验证该方向是否可前进?
是的,每次机器人向右转后,都需要再次调用robot.move()来验证该方向是否可前进。这是因为机器人的当前朝向已经改变,需要重新检查新的朝向是否有障碍。如果robot.move()返回True,则继续递归探索新的格子;如果返回False,则继续向右转,尝试下一个方向。这个过程确保了机器人能够检查所有可能的方向。

相关问题

墙与门

墙与门