返回

LeetCode 1030:畅游矩阵之序之旅,距离优先,单元格排队

前端

逐层探索,步步为营

  1. 矩阵初始化:

    我们把给定矩阵看作一个棋盘,每个单元格都是一个等待探索的方块。为了方便计算距离,我们以矩阵左上角的单元格 (0, 0) 作为坐标原点,并定义一个距离函数 dist(r, c) 来计算单元格 (r, c) 与原点的距离。

  2. 广度优先搜索:

    我们采用广度优先搜索算法来遍历矩阵,从原点 (0, 0) 开始,依次访问其相邻单元格,并计算它们与原点的距离。当我们访问一个单元格时,我们会将其标记为已访问,以避免重复访问。

  3. 队列辅助,有序排列:

    为了按照距离顺序排列单元格,我们使用一个队列来存储已访问的单元格。队列遵循先进先出(FIFO)原则,这意味着我们首先访问的单元格也会首先出列。这样,当我们从队列中取出单元格时,它们就已经按照距离顺序排列好了。

示例解析,一览无余

以一个 3 行 4 列的矩阵为例:

[[1, 2, 3, 4],
 [5, 6, 7, 8],
 [9, 10, 11, 12]]

从原点 (0, 0) 开始,我们首先访问其相邻单元格 (0, 1)、(1, 0) 和 (1, 1)。这些单元格的距离分别为 1、1 和 2。我们把它们放入队列中,并标记为已访问。

然后,我们从队列中取出距离最近的单元格 (0, 1),并访问其相邻单元格 (0, 2) 和 (1, 2)。这两个单元格的距离分别为 2 和 3。我们把它们放入队列中,并标记为已访问。

继续这个过程,我们最终会访问完所有单元格,并按照距离顺序将它们排列在队列中:

[(0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2), (2, 3)]

代码实现,巧夺天工

def all_cells_dist_order(R, C, r0, c0):
    """
    :type R: int
    :type C: int
    :type r0: int
    :type c0: int
    :rtype: List[List[int]]
    """
    # 初始化矩阵并标记原点
    matrix = [[0] * C for _ in range(R)]
    matrix[r0][c0] = 1

    # 初始化队列和已访问集合
    queue = [(r0, c0)]
    visited = set()

    # 广度优先搜索
    while queue:
        r, c = queue.pop(0)
        visited.add((r, c))

        # 访问相邻单元格
        for nr, nc in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:
            if 0 <= nr < R and 0 <= nc < C and (nr, nc) not in visited:
                matrix[nr][nc] = matrix[r][c] + 1
                queue.append((nr, nc))

    # 从矩阵中提取单元格坐标
    cells = []
    for r in range(R):
        for c in range(C):
            if matrix[r][c] > 0:
                cells.append([r, c])

    # 按照距离顺序排列单元格
    cells.sort(key=lambda cell: matrix[cell[0]][cell[1]])

    return cells

结语:算法之美,探索无止

LeetCode 1030 题看似简单,却蕴含着算法的精妙之处。广度优先搜索算法的巧妙运用,让距离优先的原则得以实现。通过队列的辅助,单元格按照距离顺序排列,为我们呈现了一场算法之美的视觉盛宴。

无论是解决编程难题,还是应对实际生活中的挑战,算法的应用无处不在。LeetCode 1030 题正是算法学习路上的一个缩影,激励我们不断探索、不断进步,在算法的世界里大放异彩。