Leetcode 59:螺旋矩阵 II(最详细的解法!!!)

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

示例:

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

解题思路

这个问题是之前问题Leetcode 54:螺旋矩阵(最详细的解法!!!)的拓展。实际上对前面的问题稍加修改即可,我们将每次访问的元素添加到对应的二维数组即可。

class Solution:
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        result = [[0]*n for _ in range(n)]
        x1, y1, x2, y2, k = 0, 0, n-1, n-1, 1
        while x1 <= x2 and y1 <= y2:
            for i in range(x1, x2+1):
                result[y1][i] = k
                k += 1
          
            for j in range(y1+1, y2+1):
                result[j][x2] = k
                k += 1

            if x1 < x2 and y1 < y2:
                for i in range(x2-1, x1, -1):
                    result[y2][i] = k
                    k += 1

                for j in range(y2, y1, -1):
                    result[j][x1] = k
                    k += 1
            
            x1 += 1
            y1 += 1
            x2 -= 1
            y2 -= 1

        return result

但是这种写法针对矩形的,对于正方形,我们是不是可以将代码更加美化一下?我们定义对应点的坐标为(i,j),每次移动的向量为(di,dj)。现在我们的问题就变成了,对于每个点每次移动的向量是什么样的。我们还是按照之前的次序先向右移动,也就是此时的向量为(0,1)(注意我们这里使用行列为坐标,而不是笛卡尔坐标)。那么我们什么时候变换向量呢?显然是到达边界的时候啊?但是这样做我们又会陷入到前面写法的困境中(什么时候是边界)。我们有一种更为巧妙地办法,我们可以判断A[(i+di)%n][(j+di)%n]是不是大于0,如果大于0的话,说明我们沿这个方向上的所有点都已经填满了,所以我们变换向量,很显然这里我们变为(-1,0),抽象为从当前的方向向右转,也就是变为(dj,-di)

    ||  =>  |9|  =>  |8|      |6 7|      |4 5|      |1 2 3|
                     |9|  =>  |9 8|  =>  |9 6|  =>  |8 9 4|
                                         |8 7|      |7 6 5|

这样我们就通过顺时针的操作将数都填到了数组中。

class Solution:
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        A = [[0]*n for _ in range(n)]
        i, j, di, dj = 0, 0, 0, 1
        for k in range(1,n**2+1):
            A[i][j] = k  
            if A[(i+di)%n][(j+dj)%n]:
                di, dj = dj, -di

            i += di
            j += dj
            
        return A 

reference:

https://leetcode.com/problems/spiral-matrix-ii/discuss/22282/4-9-lines-Python-solutions

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值