LeetCode 1030:畅游矩阵之序之旅,距离优先,单元格排队
2024-01-28 07:17:38
逐层探索,步步为营
-
矩阵初始化:
我们把给定矩阵看作一个棋盘,每个单元格都是一个等待探索的方块。为了方便计算距离,我们以矩阵左上角的单元格 (0, 0) 作为坐标原点,并定义一个距离函数
dist(r, c)
来计算单元格 (r, c) 与原点的距离。 -
广度优先搜索:
我们采用广度优先搜索算法来遍历矩阵,从原点 (0, 0) 开始,依次访问其相邻单元格,并计算它们与原点的距离。当我们访问一个单元格时,我们会将其标记为已访问,以避免重复访问。
-
队列辅助,有序排列:
为了按照距离顺序排列单元格,我们使用一个队列来存储已访问的单元格。队列遵循先进先出(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 题正是算法学习路上的一个缩影,激励我们不断探索、不断进步,在算法的世界里大放异彩。