【力扣】885:螺旋矩陣 III

題目描述

在 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章