1. 初始化阶段
-
创建矩阵:
-
确定起始位置:
r, c = 0, n - 1设定了起始坐标,其中r表示行坐标,初始化为 0,对应矩阵的第一行;c表示列坐标,初始化为n - 1,对应矩阵第一行的最后一列,也就是整个蛇形填充的起始位置。 -
初始化填充数字与方向相关变量:
a = 1定义了用于填充矩阵的数字变量,从 1 开始,后续会按顺序依次填充到矩阵的各个位置中。d = [(1, 0), (0, -1), (-1, 0), (0, 1)]创建了一个包含四个元组的列表,每个元组代表了在矩阵中移动的方向偏移量。具体来说,(1, 0)表示向下移动一行(行坐标加 1,列坐标不变);(0, -1)表示向左移动一列(行坐标不变,列坐标减 1);(1, 0)表示向上移动一行(行坐标减 1,列坐标不变);(0, 1)表示向右移动一列(行坐标不变,列坐标加 1)。这些方向偏移量用于控制填充数字时在矩阵中的移动方向。i = 0是方向索引变量,初始化为 0,表示一开始按照d列表中第一个方向元组(1, 0)所代表的方向(向下)进行移动填充。
2. 循环填充阶段(核心逻辑)
for _ in range(n * n): 这个循环会执行 n * n 次,因为 n x n 矩阵总共有 n * n 个元素,所以通过这个循环能确保矩阵的每一个位置都被填充到。
-
填充当前位置:
m[r][c] = a将当前的数字a填充到矩阵m中由当前坐标r(行)和c(列)所确定的位置上。 -
准备移动到下一个位置:
a += 1把填充数字a的值增加 1,这样下一次填充时就能使用下一个顺序的数字了。
然后通过nr = r + d[i][0]和nc = c + d[i][1]计算出按照当前方向移动后下一个位置的行坐标nr和列坐标nc。这里是利用了之前定义的方向偏移量列表d以及当前方向索引i,根据当前方向来获取对应的坐标变化量,从而确定下一个位置的坐标。 -
方向调整判断与操作:
if (nr < 0 or nr >= n or nc < 0 or nc >= n or m[nr][nc]!= 0):这个条件判断语句起着关键作用,它检查下一个位置(由nr和nc确定)是否出现以下两种情况:- 越界情况:如果
nr小于 0 或者大于等于n,或者nc小于 0 或者大于等于n,意味着下一个位置超出了矩阵的边界范围,当前方向不能继续沿着该方向走了,需要改变方向。 - 已填充情况:如果
m[nr][nc]不等于 0,说明下一个位置已经被填充过数字了,同样需要改变方向,不能重复填充。
当满足上述条件时,执行i = (i + 1) % 4,通过取余操作让方向索引i在 0 到 3 之间循环变化,从而切换到下一个方向(按照顺时针顺序切换方向,因为d列表中方向是按顺时针顺序定义的)。接着再重新通过nr = r + d[i][0]和nc = c + d[i][1]根据新的方向计算下一个有效位置的坐标。
- 越界情况:如果
-
更新当前位置坐标:
最后r, c = nr, nc将当前位置的坐标更新为新计算出来的下一个有效位置的坐标,这样在下一轮循环时,就能基于新位置继续进行数字填充以及后续的操作了。