螺旋上三角与螺旋矩阵的通用算法 python

对于螺旋上三角和螺旋矩阵来说,其实可以归类为一类问题,都是从(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)

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值