返回

深入剖析 LeetCode 874:破解行走机器人的迷局

见解分享

前言

在编程的世界中,算法的掌握是一个程序员成长的必经之路。LeetCode 作为算法练习的权威平台,汇集了海量优质题目,为程序员们提供了磨炼技艺的绝佳场所。LeetCode 874 "模拟行走机器人" 题目看似简单,实则暗藏玄机,需要我们深入理解算法本质,巧妙运用数据结构和算法策略,才能破解其奥秘。

题目解析

题目

给定一个机器人,机器人只能在x轴和y轴上移动,每次移动只能向左、右、上、下移动一个单位。机器人从(0,0)的起点出发,最终的目标是到达(target[0], target[1])的终点。每一步,机器人都会遇到一些障碍物,这些障碍物用一个布尔数组 obstacles 表示。障碍物位于数组中为 true 的位置。

返回机器人能否达到终点。

示例:

输入:target = [3,2], obstacles = [[0,1],[0,2],[0,3],[1,2],[2,2],[3,1]]
输出:false
解释:机器人无法穿过障碍物。

破解之道

本题看似是一道简单的寻路问题,但由于障碍物的存在,使得路径变得复杂,传统的暴力搜索方法效率较低,无法满足题目要求。因此,我们需要采用更为高效的算法策略,即广度优先搜索(BFS)。

BFS是一种图论算法,通过不断探索当前节点的相邻节点,层层深入,最终找到目标节点。在LeetCode 874中,我们将机器人所在的位置视为图中的节点,机器人每次移动方向视为节点的相邻边,从而构建出一个无向图。障碍物则被视为无法通行的边。

class Solution:
    def robotSim(self, target: List[int], obstacles: List[List[int]]) -> int:
        # 构建一个集合,存储障碍物的位置,加速查询
        obstacles = set(tuple(obs) for obs in obstacles)
        
        # 初始化队列,存储当前位置和方向
        queue = [(0, 0, 0)]
        # 四个方向的移动方式
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
        
        # 广度优先搜索
        max_dis = 0
        while queue:
            x, y, dis = queue.pop(0)
            max_dis = max(max_dis, dis)
            # 遍历四个方向
            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                # 判断是否到达终点
                if [nx, ny] == target:
                    return dis + 1
                # 判断是否遇到障碍物或越界
                if (nx, ny) not in obstacles and 0 <= nx < target[0] and 0 <= ny < target[1]:
                    queue.append((nx, ny, dis + 1))
        
        return -1

算法分析

BFS算法的复杂度主要取决于图中节点的个数和边的个数。在LeetCode 874中,节点的个数为target[0] * target[1],边的个数为4 * target[0] * target[1](每个节点有4条边)。因此,BFS算法的总时间复杂度为O(target[0] * target[1])。

总结

通过对LeetCode 874 "模拟行走机器人" 题目的深入剖析,我们了解了BFS算法在寻路问题中的应用。BFS算法通过层层深入,广度优先地探索节点,从而高效地找到目标节点,是一种高效且通用的图论算法。在今后的编程实践中,BFS算法将成为我们解决寻路问题的有力武器。

扩展阅读: