1. 程式人生 > >Leetcode 59:螺旋矩陣 II(最詳細的解法!!!)

Leetcode 59:螺旋矩陣 II(最詳細的解法!!!)

給定一個正整數 n,生成一個包含 1 到n2n^2 所有元素,且元素按順時針順序螺旋排列的正方形矩陣。

示例:

輸入: 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)

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:

如有問題,希望大家指出!!!