[LeetCode解題攻略] 54. Spiral Matrix

更新於 發佈於 閱讀時間約 7 分鐘

題目描述

題目要求

給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。

限制條件

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

雖然 mn 只有 最多 10,但我們仍希望找到高效的解法。


範例

範例 1:

輸入: matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
輸出: [1,2,3,6,9,8,7,4,5]
raw-image


範例 2:

輸入: matrix = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
輸出: [1,2,3,4,8,12,11,10,9,5,6,7]
raw-image



解題思路

這題的關鍵是按照螺旋順序遍歷矩陣,我們有幾種不同的解法:

思路 1:模擬螺旋順序(推薦)

  • 用四個變數 top, bottom, left, right 來標記矩陣的邊界,每次遍歷完一條邊就縮小範圍。
  • 時間複雜度:O(m * n),因為每個元素都會被訪問一次。

思路 2:使用方向變換

  • 使用 方向變量 [(0,1), (1,0), (0,-1), (-1,0)] 來控制遍歷順序,遇到邊界時切換方向。
  • 時間複雜度:O(m * n),但要額外處理訪問過的元素。




解法一:模擬螺旋順序

思路

  1. 設定 top, bottom, left, right 來標記矩陣範圍。
  2. left → righttop → bottomright → leftbottom → top 依序收縮範圍。
  3. top <= bottomleft <= right 時繼續遍歷。

程式碼

class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix:
return []

result = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1

while top <= bottom and left <= right:
# 往右
for i in range(left, right + 1):
result.append(matrix[top][i])
top += 1

# 往下
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1

# 確保還有行
if top <= bottom:
# 往左
for i in range(right, left - 1, -1):
result.append(matrix[bottom][i])
bottom -= 1

# 確保還有列
if left <= right:
# 往上
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1

return result

時間與空間複雜度

  • 時間複雜度:O(m * n)(遍歷所有元素一次)
  • 空間複雜度:O(1)(只使用額外的 result 陣列)

解法二:使用方向變換

思路

  1. 使用 directions = [(0,1), (1,0), (0,-1), (-1,0)] 來控制方向變化。
  2. visited 紀錄哪些元素已經走過,遇到邊界或已訪問的格子就改變方向。

程式碼

class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix:
return []

m, n = len(matrix), len(matrix[0])
visited = [[False] * n for _ in range(m)]
result = []

directions = [(0,1), (1,0), (0,-1), (-1,0)] # 右, 下, 左, 上
x, y, d = 0, 0, 0 # 起始位置 & 方向索引

for _ in range(m * n):
result.append(matrix[x][y])
visited[x][y] = True
new_x, new_y = x + directions[d][0], y + directions[d][1]

if 0 <= new_x < m and 0 <= new_y < n and not visited[new_x][new_y]:
x, y = new_x, new_y
else:
d = (d + 1) % 4 # 改變方向
x, y = x + directions[d][0], y + directions[d][1]

return result

時間與空間複雜度

  • 時間複雜度:O(m * n)(每個元素遍歷一次)
  • 空間複雜度:O(m * n)(使用 visited 紀錄已訪問的格子)

結論

這題相較之下適合用 模擬螺旋順序 來解,因為它的 O(1) 空間複雜度,不需要額外儲存空間。


留言
avatar-img
留言分享你的想法!
avatar-img
追極光的北極熊|軟體工程師的小天地
9會員
150內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
2025/03/18
52. N-Queens II 題目是經典的組合優化問題,它要求解出一個 n x n 的棋盤上,放置 n 個皇后,且要求皇后們不互相攻擊,並計算出所有合法的解的數量。
2025/03/18
52. N-Queens II 題目是經典的組合優化問題,它要求解出一個 n x n 的棋盤上,放置 n 個皇后,且要求皇后們不互相攻擊,並計算出所有合法的解的數量。
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定我們一個二維陣列,要求我們計算內部元素相同的column row pairs總共有多少條? 註: pair的定義就是row i 和 column j 彼此內部元素值都相同,這樣就算一條pair。 題目的原文敘述 測試範例 Example 1: Input: gr
Thumbnail
題目敘述 題目會給定我們一個二維陣列,要求我們計算內部元素相同的column row pairs總共有多少條? 註: pair的定義就是row i 和 column j 彼此內部元素值都相同,這樣就算一條pair。 題目的原文敘述 測試範例 Example 1: Input: gr
Thumbnail
題目敘述 題目給定我們一個輸入陣列nums 要求我們以正、負交叉排列的方式重組陣列,並且必須保持原本的相對順序。 並且以陣列的形式輸出返回答案。 例[5, 1, -2, -3] 重排後為 [5, -2, 1, -3] 題目的原文敘述 測試範例 Example 1: Input:
Thumbnail
題目敘述 題目給定我們一個輸入陣列nums 要求我們以正、負交叉排列的方式重組陣列,並且必須保持原本的相對順序。 並且以陣列的形式輸出返回答案。 例[5, 1, -2, -3] 重排後為 [5, -2, 1, -3] 題目的原文敘述 測試範例 Example 1: Input:
Thumbnail
題目敘述 題目會給定一個陣列nums 和 給定的k值,要求我們找出陣列裡第k大的元素。 題目的原文敘述 測試範例 Example 1: Input: nums = [3,2,1,5,6,4], k = 2 Output: 5 第二大的元素為5​ Example 2: Input:
Thumbnail
題目敘述 題目會給定一個陣列nums 和 給定的k值,要求我們找出陣列裡第k大的元素。 題目的原文敘述 測試範例 Example 1: Input: nums = [3,2,1,5,6,4], k = 2 Output: 5 第二大的元素為5​ Example 2: Input:
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News