題目描述
在 R 行 C 列的矩陣上,我們從 (r0, c0) 面朝東面開始
這裏,網格的西北角位於第一行第一列,網格的東南角位於最後一行最後一列。
現在,我們以順時針按螺旋狀行走,訪問此網格中的每個位置。
每當我們移動到網格的邊界之外時,我們會繼續在網格之外行走(但稍後可能會返回到網格邊界)。
最終,我們到過網格的所有 R * C 個空間。
按照訪問順序返回表示網格位置的座標列表。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/spiral-matrix-iii
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
實例:
輸入:R = 1, C = 4, r0 = 0, c0 = 0
輸出:[[0,0],[0,1],[0,2],[0,3]]
輸入:R = 5, C = 6, r0 = 1, c0 = 4
輸出:[[1,4],[1,5],[2,5],[2,4],[2,3],[1,3],[0,3],[0,4],[0,5],[3,5],[3,4],[3,3],[3,2],[2,2],[1,2],[0,2],[4,5],[4,4],[4,3],[4,2],[4,1],[3,1],[2,1],[1,1],[0,1],[4,0],[3,0],[2,0],[1,0],[0,0]]
算法思路
雖然類似【螺旋矩陣I】、【螺旋矩陣II】等,但其實有很大的區別。
首先是沒有了矩陣,使得判斷是否走過需要用一個表來記錄,最好是使用哈希集合。
最開始的部分:
class Solution:
def spiralMatrixIII(self, R: int, C: int, r0: int, c0: int):
m, n = R, C
i, j = r0, c0
k, v = [(0, 1), (1, 0), (0, -1), (-1, 0)], 0
ls = []
d = set()
然後進入while循環,在座標遍歷轉彎這裏,我考慮了很多,但是越想越懵,最後考慮座標每更新一次,就轉彎一次,遍歷k,v
組合在一起用以控制遍歷轉彎。
然後更新後的座標如果已經被記錄,那麼就恢復爲原座標,不轉彎地更新一次,再更新(哇 說起來好繞啊!)
while True:
while 0 <= i <= m - 1 and 0 <= j <= n - 1:
if (i, j) in d: break
ls.append([i, j])
d.add((i, j))
i += k[v % 4][0]
j += k[v % 4][1]
v += 1
if (i,j) in d:
v-=1
i -= k[v % 4][0]
j -= k[v % 4][1]
v-=1
i += k[v % 4][0]
j += k[v % 4][1]
v+=1
而一旦脫離矩陣的範圍,就回滾一次,(突然間覺得回滾這個詞用得很好)
v -= 1
i -= k[v % 4][0]
j -= k[v % 4][1]
回滾以後,轉彎,進入下一個while循環:因爲這個時候座標將會貼着邊緣運動,直到找到未記錄的座標。
while (i,j)in d:
i += k[v % 4][0]
j += k[v % 4][1]
if not(0 <= i <= m - 1 and 0 <= j <= n - 1):
i -= k[v % 4][0]
j -= k[v % 4][1]
v+=1
v+=1
這就是整體的框架,那麼當所有的座標都被記錄,這時就會跳出第一個while,進行if len(d)==m*n:break
判斷,是否結束True循環。
完整算法
class Solution:
def spiralMatrixIII(self, R: int, C: int, r0: int, c0: int):
m, n = R, C
i, j = r0, c0
k, v = [(0, 1), (1, 0), (0, -1), (-1, 0)], 0
ls = []
d = set()
while True:
while 0 <= i <= m - 1 and 0 <= j <= n - 1:
if (i, j) in d: break
ls.append([i, j])
d.add((i, j))
i += k[v % 4][0]
j += k[v % 4][1]
v += 1
if (i,j) in d:
v-=1
i -= k[v % 4][0]
j -= k[v % 4][1]
v-=1
i += k[v % 4][0]
j += k[v % 4][1]
v+=1
v -= 1
i -= k[v % 4][0]
j -= k[v % 4][1]
v+=1
if len(d)==m*n:break
while (i,j)in d:
i += k[v % 4][0]
j += k[v % 4][1]
if not(0 <= i <= m - 1 and 0 <= j <= n - 1):
i -= k[v % 4][0]
j -= k[v % 4][1]
v+=1
v+=1
return ls
執行用時 :160 ms, 在所有 Python3 提交中擊敗了29.06%的用戶
內存消耗 :15.6 MB, 在所有 Python3 提交中擊敗了100.00%的用戶
以上算法以解決問題爲目標,所以是存在優化空間的。
第一版:
class Solution:
def spiralMatrixIII(self, R: int, C: int, r0: int, c0: int):
m, n ,i, j= R, C,r0, c0
k, v = [(0, 1), (1, 0), (0, -1), (-1, 0)], 0
ls ,d= [],set()
while True:
while 0 <= i <= m - 1 and 0 <= j <= n - 1:
if (i, j) in d: break
ls.append([i, j])
d.add((i, j))
if (i+ k[v % 4][0],j+k[v % 4][1]) in d:
v-=1
i += k[v % 4][0]
j += k[v % 4][1]
v+=1
v -= 1
i -= k[v % 4][0]
j -= k[v % 4][1]
v+=1
if len(d)==m*n:break
while (i,j)in d:
i += k[v % 4][0]
j += k[v % 4][1]
if not(0 <= i <= m - 1 and 0 <= j <= n - 1):
i -= k[v % 4][0]
j -= k[v % 4][1]
v+=1
v+=1
return ls