对于螺旋上三角和螺旋矩阵来说,其实可以归类为一类问题,都是从(0,0)开始从外圈依次遍历到内圈,但不同的思路会产生不同的解法,大致可以分为以下两种解题思路:
1、以方向为主的改变坐标(x,y)。螺旋上三角只有三个方向,即:每次向右移动一个单位(x++),每次向左下移动一个单位(x--,y++),每次向上移动一个单位(y--),遇到边界或者已走过的转角则改变方向。螺旋矩阵则是有四个方向,向右(x++),向下(y++),向左(x--),向上(y--)。
2、已边界为主的判断外圈x及y的取值范围,每循环就将边界走一圈,遍历一次就缩小一次范围。
以上两种方式,网上都已经有解题代码,本文的解题思路中心是从(0,-1)开始以方向为主的坐标移动,适用于这一类的所有螺旋,代码简洁,详情见案例:
第一题:螺旋上三角
你设计一个用于填充n阶方阵的上三角区域的程序,使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。
当n=3时,输出:
1 2 3
6 4
5
当n=4时,输出:
1 2 3 4
9 10 5
8 6
7
要求用户输入整数n(3~20)
解题思路:将位移放到list列表中,通过获取list下标来判断方向的改变,以及每次改变后需要遍历的次数
代码:
def func(n, x, y, num):
matrix = [[0] * (n - i) for i in range(n)]
move_list = [(0, 1), (1, -1), (-1, 0)]
for i in range(n, 0, -1):
for _ in range(i):
x += move_list[(n - i) % 3][0]
y += move_list[(n - i) % 3][1]
num += 1
matrix[x][y] = num
[print(' '.join(map(str, i))) for i in matrix]
if __name__ == "__main__":
func(int(input().strip()), 0, -1, 0)
第二题:螺旋矩阵(n * n)
解题思路:
螺旋矩阵需要改变方向的次数:2 * n - 1
每次改变方向后需要走的步数:n - math.ceil(i / 2)
代码:
def func(n, x, y, num):
matrix = [[0] * n for _ in range(n)]
move_list = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for i in range(2 * n - 1):
for _ in range(n - math.ceil(i / 2)):
x += move_list[i % 4][0]
y += move_list[i % 4][1]
num += 1
matrix[x][y] = num
print(matrix)
if __name__ == "__main__":
func(int(input().strip()), 0, -1, 0)
第三题:生成螺旋矩阵(n * m)
n * m 长方形矩阵(matrix)中生成一个包含1到n * m所有元素,元素按顺时针螺旋排列。
输入 n 和 m,返回列表matrix,如图:
输入: 6 5
解题思路:
如果 n >= m
螺旋矩阵需要改变方向的次数:2 * m - 1
每次改变方向后需要走的步数:横轴:n - int(i / 2) 纵轴:m - int((i + 1) / 2)
如果 n < m
螺旋矩阵需要改变方向的次数:2 * n
每次改变方向后需要走的步数:横轴:n - int(i / 2) 纵轴:m - int((i + 1) / 2)
代码:
def func(n, m, x, y, num):
matrix = [[0] * n for _ in range(m)]
move_list = [(0, 1), (1, 0), (0, -1), (-1, 0)]
change_time = 2 * m - 1 if n >= m else 2 * n
for i in range(change_time):
step = n - int(i / 2) if i % 2 == 0 else m - int((i + 1) / 2)
for _ in range(step):
x += move_list[i % 4][0]
y += move_list[i % 4][1]
num += 1
matrix[x][y] = num
print(matrix)
if __name__ == "__main__":
n, m = map(int, input().strip().split())
func(n, m, 0, -1, 0)
第四题:遍历螺旋矩阵(n * m)
解题思路:
跟我写的上一题类似,只不过一个是赋值,一个是遍历
代码:
def func(matrix, n, m, x, y):
result_list = []
move_list = [(0, 1), (1, 0), (0, -1), (-1, 0)]
change_time = 2 * m - 1 if n >= m else 2 * n
for i in range(change_time):
step = n - int(i / 2) if i % 2 == 0 else m - int((i + 1) / 2)
for _ in range(step):
x += move_list[i % 4][0]
y += move_list[i % 4][1]
result_list.append(matrix[x][y])
print(result_list)
if __name__ == "__main__":
matrix = eval(input().strip().split('=')[1])
func(matrix, len(matrix[0]), len(matrix), 0, -1)