給定一個 n × n 的二維矩陣 matrix 表示一個圖像。請你將圖像順時針旋轉 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]
提示:
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
【分析】
方法一:使用輔助數組
以題目中的示例二作爲例子:
分析將圖像旋轉90度之後,這些數字出現在什麼位置。
對於矩陣中的第一行而言,旋轉後,它出現在倒數第一列的位置:
並且,第一行的第x個元素在旋轉後恰好是倒數第一列的第x個元素。
對於矩陣中第二行而言,旋轉後,它出現在倒數第二列的位置:
對於矩陣中的第三行和第四行同理。這樣我們可以得到規律:
對於矩陣中的第i行的第j個元素,旋轉後,它出現在倒數第i列的第j個位置。
我們將該規律翻譯成代碼。由於矩陣中的行列從0開始計數,因此對於矩陣中的元素matrix[row][col],在旋轉後,它的新位置爲matrix[col][n - row - 1],比如上面矩陣中的數字2,matrix[1][0]==>matrix[0][4-1-1]=matrix[0][2]。
這樣以來,我們使用一個與matrix大小相同的輔助數組matrixnew,臨時存儲旋轉後的結果。我們遍歷matrix只的每一個元素,根據上述規則將該元素存放到matrixnew中對應位置,在遍歷完成後,再將matrixnew中的結果複製到原數組中即可。
class Solution: def rotate(self, matrix: List[List[int]]) -> None: """ Do not return anything, modify matrix in-place instead. """ n = len(matrix) # Python 這裏不能 matrix_new = matrix 或 matrix_new = matrix[:] 因爲是引用拷貝 matrix_new = [[0] * n for _ in range(n)] for i in range(n): for j in range(n): matrix_new[j][n - i - 1] = matrix[i][j] # 不能寫成matrix = matrix_new matrix[:] = matrix_new
時間複雜度:O(N2),其中N是matrix的邊長。
空間複雜度:O(N2),我們需要使用一個和matrix大小相同的輔助數組。
方法二:原地旋轉
題目中要求我們嘗試在不使用額外內存空間的情況下進行矩陣的旋轉,也就是說,我們需要原地旋轉這個矩陣,那麼我們如果在方法一的基礎上完成原地旋轉呢?
我們觀察方法一中的關鍵等式:
matrix_new[j][n - i - 1] = matrix[i][j]
它阻止了我們進行原地旋轉,這是因爲如果我們直接將matrix[row][col]放到原矩陣中的目標位置matrix[col][n - row - 1]:
matrix_new[j][n - i - 1] = matrix[i][j]
原矩陣中的matrix[col][n - row - 1]就被覆蓋掉了,這並不是我們想要的結果。因此我們可以考慮用一個臨時變量temp暫存matrix[col][n - row - 1]的值,這樣雖然matrix[col][n - row - 1]被覆蓋了,還是可以通過temp獲取到它原來的值:
那麼matrix[col][n - row - 1]經過旋轉之後會到哪個位置上呢?我們還是使用方法一中的關鍵等式,不過這一次,我們需要將:
代入關鍵等式,就可以得到:
同樣地,直接賦值會覆蓋掉matrix[n - row - 1][n - col - 1]原來的值,因此我們還是需要使用一個臨時變量進行存儲,不過這次,我們可以直接使用之前的臨時變量temp:
我們再重複一次之前的操作, matrix[n - row - 1][n - col - 1]經過旋轉之後會到哪一個位置上呢?
自己看吧👀https://leetcode.cn/problems/rotate-image/solution/xuan-zhuan-tu-xiang-by-leetcode-solution-vu3m/
class Solution: def rotate(self, matrix: List[List[int]]) -> None: n = len(matrix) for i in range(n // 2): for j in range((n + 1) // 2): matrix[i][j], matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1] \ = matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1], matrix[i][j]