面試題 01.07. 旋轉矩陣
題目來源:https://leetcode-cn.com/problems/rotate-matrix-lcci
題目
給你一幅由 N × N 矩陣表示的圖像,其中每個像素的大小爲 4 字節。請你設計一種算法,將圖像旋轉 90 度。
不佔用額外內存空間能否做到?
示例 1:
給定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋轉輸入矩陣,使其變爲:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
給定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋轉輸入矩陣,使其變爲:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
解題思路
思路:通過翻轉替代旋轉
先看示例 1:
給定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋轉輸入矩陣,使其變爲:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
題目要求選擇旋轉 90 度,逐行看旋轉之後,每個元素對應的座標如何變化。
第一行旋轉之後的變化:
在這裏,可以看到,第一行的第 n 個元素,旋轉之後變爲倒數第一列的第 n 個元素。
第二行旋轉之後的變化:
同樣,第二行的第 n 個元素,選擇之後,是倒數第二列的第 n 個元素。
第三行同理。那麼可以得出結論:
原矩陣經過旋轉後,原矩陣第 i 行第 j 個元素,將會出現在倒數第 i 列第 j 個位置。
將上面的結論轉換成代碼,題目明確給出矩陣爲 N * N,設矩陣長度爲 length,可以表示爲:
matrix[row][col] ⇒ matrix[col][length-row-1]
現在,則需要對矩陣進行轉換,由上左邊式子變爲右邊式子。本篇運用的是翻轉的思路。
假設對原矩陣進行水平翻轉,則:
matrix[row][col] ⇒ matrix[length-row-l][col]
假設對原矩陣進行主對角線翻轉,則:
matrix[row][col] ⇒ matrix[col][row]
仔細對比前面結論轉化的式子,將這兩次翻轉結合起來,先進行水平翻轉,再進行主對角線翻轉,則:
matrix[row][col] ⇒ matrix[length-row-1][col]
⇒ matrix[col][length-row-1]
所得出的式子與上面的式子一模一樣。
那麼就可以按照這個思路,對矩陣進行相應的翻轉,得出最終結果。
還有一種翻轉的方式,同樣可以達到最終效果,如下:
對原矩陣進行主對角線翻轉,則:
matrix[row][col] ⇒ matrix[col][row]
對原矩陣進行垂直翻轉,則:
matrix[row][col] ⇒ matrix[row][length-col-1]
同樣,將兩個翻轉形式結合起來,先進行主對角線翻轉,再進行垂直翻轉,可得:
matrix[row][col] ⇒ matrix[col][row]
⇒ matrix[col][length-row-1]
與上面結論中的式子相比,得出的結論同樣一致。
具體的代碼如下,採用第二種翻轉方式。
代碼實現
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
length = len(matrix)
# 進行主對角線翻轉
for i in range(length):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 進行垂直翻轉
for i in range(length):
for j in range(length // 2):
matrix[i][j], matrix[i][length-j-1] = matrix[i][length-j-1], matrix[i][j]
實現結果
以上就是通過翻轉的思想代替旋轉,來解決《面試題 01.07. 旋轉矩陣》問題的主要內容
歡迎關注微信公衆號《書所集錄》