螺旋矩阵:给定一个正整数,生成一个包含 1 到 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
比如:
1 2 3
8 9 4
7 6 5
具体步骤
这种题目需要明白过程的模拟情况。在整个过程中,画矩阵的过程如下:
- 步骤1:填充上行,从左往右画
- 步骤2:填充右行,从上往下画
- 步骤3:填充下行,从右往左画
- 步骤4:填充左行,由下往上画
起点终点判定
此外,在整个过程中,我们需要注意每次画的过程中的起点和终点。
上面2个图分别是和时所形成的螺旋矩阵,里面的黄色底数字则是需要在画矩阵过程中的起始点/终止点。
我们以举例,此外,矩阵中坐标以为开始
-
步骤1:其中数字和数字的位置分别为和,其横坐标一致,但纵坐标的和为,同样的,以数字和数字为例,其位置为和,其横坐标一致,但纵坐标的和为。因此,对于步骤1而言,其开始的横坐标为,纵坐标为。
-
步骤2:我们以数字和数字为例,其位置为和,纵坐标一致,但横坐标的和为。同样的,数字和数字,其横坐标一致,但纵坐标的和为。因此,对于步骤2而言,其开始的横坐标为,而纵坐标为。
-
步骤3:我们以数字和数字为例,其位置为和,其横坐标一致,但纵坐标的和为。(省略了,不写)。因此,对于步骤3而言,其开始的横坐标为,纵坐标为。
-
步骤4:我们以数字和数字为例,其位置为和,其纵坐标一致,但横坐标的和为。(省略了,不写)。因此,对于步骤4而言,其开始的横坐标为,纵坐标为。
需要注意的是,由于我们每次画圈,均会在上下左右进行一次,因此我们一共会画次。而当为奇数时,最中间的数字是没法画上去的,因此我们需要对此进行特定的判断以及填充:
if n % 2 != 0:
matrix[int(n/2)][int(n/2)] = n * n
大循环起点、终点判断:可以看出,每次经历一次步骤1-步骤4后,步骤1的起点位置都会进行变化,分别是从。
闭合过程
在这个过程中,我们需要注意矩阵填充过程中是前开后闭还是前闭后开。不过,我们统一采取前闭后开。比如下面这个过程:
这样子就能保证代码编写过程的一致性。
代码
def generateMatrix(self, n: int) -> List[List[int]]:
"""
n: the size of matrix
"""
matrix = [[0 for _ in range(n)] for _ in range(n)]
big_loop = int(n/2)
start_x = 0
start_y = 0
count = 1
for _ in range(big_loop):
# 步骤1
for i in range(start_x, n-start_x-1):
matrix[start_y][i] = count
count += 1
# 步骤2
for j in range(start_y, n-start_y-1):
matrix[j][n-start_x-1] = count
count += 1
# 步骤3
for i in range(n-start_y-1, start_x, -1):
matrix[n-start_y-1][i] = count
count += 1
# 步骤4
for j in range(n-start_x-1, start_x, -1):
matrix[j][start_y] = count
count += 1
start_x += 1
start_y += 1
if n % 2 != 0:
matrix[big_loop][big_loop] = count
return matrix