数组——3.螺旋矩阵II

力扣题目链接

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

示例:

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

顺时针螺旋排列的矩阵是什么意思呢,以3*3的矩阵为例

3*3=9,将1到9的数按顺序从矩阵最外圈开始排列,一圈一圈(类似贪吃蛇的感觉)向内排列,直到到达矩阵最中间。

具体的思路如《代码随想录》所示。我这里依旧对代码进行详细解释说明。

完整代码如下:

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0] * n for _ in range(n)]
        startx, starty = 0, 0               # 起始点
        loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点
        count = 1                           # 计数

        for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从1开始
            for i in range(starty, n - offset) :    # 从左至右,左闭右开
                nums[startx][i] = count
                count += 1
            for i in range(startx, n - offset) :    # 从上至下
                nums[i][n - offset] = count
                count += 1
            for i in range(n - offset, starty, -1) : # 从右至左
                nums[n - offset][i] = count
                count += 1
            for i in range(n - offset, startx, -1) : # 从下至上
                nums[i][starty] = count
                count += 1                
            startx += 1         # 更新起始点
            starty += 1

        if n % 2 != 0 :			# n为奇数时,填充中心点
            nums[mid][mid] = count 
        return nums

首先,设置一个所有数为0的n*n阶的矩阵

        nums = [[0] * n for _ in range(n)]

其中[0]*n代表矩阵第一行,例如[0]*3,则代表生成一个数组为[0,0,0]。在生成一个数组后加入n层的for循环代表生成n行与第一个数组一样的数组,最终形成n*n阶的矩阵。

        startx, starty = 0, 0               # 起始点
        loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点
        count = 1                           # 计数

上述代码中startx可以理解为第几行,starty可以理解为第几列,是为方便后面将具体数字填充至第几行第几列,这里面初始为0也是因为下标是从0开始的。

loop代表迭代次数(n除以2后的整数部分),可以理解为能在一个n*n阶的矩阵中完成几次完整的绕四边一圈的次数。同时当n为奇数时,矩阵存在最后一圈完不成的情况即矩阵存在中心点,因此用mid=n//2来表示矩阵中心点,即nums[mid][mid]为矩阵中心点。

最后一行的count=1则代表的是第一个填充的元素1。

        for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从1开始
            for i in range(starty, n - offset) :    # 从左至右,左闭右开
                nums[startx][i] = count
                count += 1

从最外圈开始第一次迭代。为保证代码统一,将每条边的元素填充方法设计为只填充至倒数第二格,如下图所示。

因此,在代码中可以体现为每条边的元素填充都是一个左闭右开区间,如n=3时,第一次迭代时 for i in range(starty, n - offset)中starty = 0 ,n-offset=2,即区间为[0,2),第一次的nums[startx][i] = count即代表nums[0][0] = 1即空矩阵第一行第一列填充为1,count+1代表下次开始填充元素为2,依次填充,这样第一条边除最后一个值便都填充完毕了。接着,依次是右边、下边以及左边。

            startx += 1         # 更新起始点
            starty += 1

最外圈的边都填充完毕后,开始对里面一圈的边进行填充,则更新起点startx和starty就可以了,迭代次数有几次则完成几圈。

        if n % 2 != 0 :			# n为奇数时,填充中心点
            nums[mid][mid] = count 
        return nums

最后,当m为奇数时,填充矩阵的中心点nums[mid][mid],将其填充为最终叠加后的count,其实也等于n*n的值,最后return整个填充完毕的螺旋矩阵nums。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值