生成旋转矩阵【python实现】

这篇博客介绍了如何使用Python生成包含1到n²所有元素,且按顺时针螺旋排列的nxn正方形矩阵。通过分析换向顺序和换向标志位,实现了一个高效的算法,能够生成指定大小的螺旋矩阵,并给出了不同n值的示例输出。

问题描述

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序
螺旋排列的 n x n 正方形矩阵 matrix 。

img

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:

输入:n = 1
输出:[[1]]

实现方式

手动写几个矩阵我们就会发现螺旋矩阵每一层边的特点。

例如:3*3,他换向的顺序为,3 2 2 1 1(每换向到一条新的边,边的数有多少,不包含上一条边的重复数)

4*4,4 3 3 2 2 1 1

5*5,5 4 4 3 3 2 2 1 1

根据这个规律,我们便能生成换向区间和计算换向标志位(相当于每一个拐弯点的值 我们是清楚的)

import numpy as np


def spiralMatrix(n):
    spiralMatrix = np.zeros([n, n], dtype=int) # 创建对应n*n的全0数组
    move = [0, 0]  # 数组坐标索引
    moveR = [0, 1] # 向右移动
    moveL = [0, -1] # 向左移动
    moveU = [-1, 0] # 向上移动
    moveD = [1, 0] # 向下移动
    
    # 螺旋矩阵换方向的顺序是右->下->左->上
    moveDirection = [moveR, moveD, moveL, moveU] # 将移动步数添加到列表,方便循环取用
    widerange = [] # 换向标志区间
    threshold = [] # 换向标志位
    acc = 0 # 计算标志位时的累加器初始化
    step = 1 # 螺旋运动时的步长
    for wide in range(1, n + 1): # 生成换向区间
        if wide != n:
            widerange.append(wide)
            widerange.append(wide)
        else:
            widerange.append(wide)
    for num in widerange[::-1]: # 生成换向标志位(对换向区间做累加)
        acc = acc + num
        threshold.append(acc)
    print(threshold)
    for id, th in enumerate(threshold): # 遍历换向标志位,到达标志位,就进行换向,进行相应的换向索引计算操作。
        while step < th:
            spiralMatrix[move[0], move[1]] = step
            step += 1
            print(move, step)
            move[0] = move[0] + moveDirection[id % 4][0]
            move[1] = move[1] + moveDirection[id % 4][1]
        if th == n ** 2: # 上面直到生成最后一位之前,都是好的,n**2无法到达,在这里我们列为特殊情况,手动让n**2到达.
            spiralMatrix[move[0], move[1]] = step

    print(spiralMatrix)
    return spiralMatrix

spiralMatrix(4)
spiralMatrix(5)
spiralMatrix(7)

result

[[ 1  2  3  4]
 [12 13 14  5]
 [11 16 15  6]
 [10  9  8  7]]
[[ 1  2  3  4  5]
 [16 17 18 19  6]
 [15 24 25 20  7]
 [14 23 22 21  8]
 [13 12 11 10  9]]
[[ 1  2  3  4  5  6  7]
 [24 25 26 27 28 29  8]
 [23 40 41 42 43 30  9]
 [22 39 48 49 44 31 10]
 [21 38 47 46 45 32 11]
 [20 37 36 35 34 33 12]
 [19 18 17 16 15 14 13]]

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值