動機
很有因緣的一題
當初自己有解出來,不過那個index的方式十分可怕,加上自己本來就不喜歡index的題目(很多時候都是考細不細心而已,想法很簡單,但是實作細節很多) 所以解完就放著了
結果某次offsite就遇到了,同時OJ的網站還十分爛,用stdout當作解答輸出!? 都什麼年代了!? debug的輸出與解答的輸出混在一起,十分痛苦
同時那個OJ還要裝browser plugin,來錄音與錄影!!?? 還讓我的mac一直叫!!
因此超不喜歡這種題目,讓人感覺回到高中或是大一 得不到演算法設計有關的啟發,就是比細心的題目 但就是有人offsite會放這種題目…
所以就重新解一次吧,把當時的錯愕了結於此
同時對於所有rotate的題目都用reverse去做就好,不然很痛苦
Problem
You are given an n x n
2D matrix
representing an image, rotate the image by 90 degrees (clockwise).
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]Output: [[7,4,1],[8,5,2],[9,6,3]]
Example 2:
Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
Example 3:
Input: matrix = [[1]]Output: [[1]]
Example 4:
Input: matrix = [[1,2],[3,4]]Output: [[3,1],[4,2]]
Constraints:
matrix.length == n
matrix[i].length == n
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
Sol
長度帶3,來推推看怎麼設定
從大的走法到小的走法
- 大的走法: 一圈一圈由外往內,直到中心點
for i in range((len(ms)+1)//2):
n = len(ms)-i*2-1+i # end of range
# (0,0) -> (1,1)
# ....
- 小的走法: 把4個點轉一圈
# (0,0) -> (0,2) -> (2,2) -> (2,0)
# (0,1) -> (1,2) -> (2,1) -> (1,0)
# (0,+1) (+1,0) (0,-1) (-1,0)
# 用把0設定成i, 2設定成n
# (i,i) -> (i,n) -> (n,n) -> (n,i)
# (i,i+1) -> (i+1,n) -> (n,n-1) -> (n-1,i)
# 把遞增量設定成a
tmp = ms[i][i+a]
ms[i][i+a] = ms[n-a][i]
ms[n-a][i] = ms[n][n-a]
ms[n][n-a] = ms[i+a][n]
ms[i+a][n] = tmp
- 小的走法要走幾次: n-i次 (目前處理範圍的總長-1次,最後一個不用轉,n與i都是index所以直接相減就是總長-1)
四個四個轉,這種座標就只能用推的
class Solution:
def rotate(self, ms: List[List[int]]) -> None:
n,a,b,prev = len(ms),0,0,ms[0][0]
# (a,b) is the starting point of each ring
while n > 0:
for k in range(n-1):
# 0,0 : 0,n-1 : n-1,n-1 : n-1,0
# 0,1 : 1,n-1 : n-1,n-1-1 : n-1-1, 0
ms[a][b+k], ms[a+k][b+n-1], ms[a+n-1][b+n-1-k], ms[a+n-1-k][b] = ms[a+n-1-k][b], ms[a][b+k], ms[a+k][b+n-1], ms[a+n-1][b+n-1-k]
a, b = a+1, b+1
n -= 2
case study
用對角線(1,5,9)去swap對面的值,之後每個row做reverse
1 2 3 1 4 7 7 4 1
4 5 6 --> 2 5 8 --> 8 5 2
7 8 9 3 6 9 9 6 3
class Solution {
public:
void rotate(vector<vector<int>>& mx) {
for(int i=0;i<mx.size();i++) {
for(int j=i+1;j<mx.size();j++) {
swap(mx[i][j],mx[j][i]);
}
reverse(mx[i].begin(),mx[i].end());
}
}
};