you are given an n x n 2d matrix representing an image.
rotate the image by 90 degrees (clockwise).
follow up:
could you do this in-place?
簡單的說就是給出一個n*n的二維數組,然後把這個數組進行90度順時針旋轉,而且不能使用額外的存儲空間。
最初拿到這道題想到的就是找出每個坐标的旋轉規律。假設我們是2*2的矩陣:
a b
c d
進行旋轉後,那麼就變成了:
c a
d b
是以就轉換成對4個數字進行輪換,而不使用額外空間的問題。最常用的交換數值而不使用額外空間的算法就是異或,比如要交換a,b的值,那麼可以寫為:
a=a^b;
b=a^b;
現在是對4個數字進行輪換,輪換後的結果為a=c,b=a,c=d,d=b;
是以改寫成異或的算法,那麼就是:
a = a ^ b ^ c ^ d;
b = a ^ b ^ c ^ d;
d = a ^ b ^ c ^ d;
c = a ^ b ^ c ^ d;
接下來就是找出二維數組中角标與a,b,c,d的關系,這個其實不難。另外,我們在進行旋轉處理時,我們隻需要處理1/4的區域即可,因為處理一次就是調整了4個數,是以我們隻處理二維數組中左上角的數值。
下面就是具體的代碼:
public void rotate(int[,] matrix)
{
int n = matrix.getlength (0);
for (var i = 0; i < (n + 1)/2; i++)
for (var j = 0; j < n/2; j++)
//var a = matrix[i, j];
//var b = matrix[j, n - i - 1];
//var d = matrix[n - i - 1, n - j - 1];
//var c = matrix[n - j - 1, i]; matrix[i, j] = matrix[i, j] ^ matrix[j, n - i - 1] ^ matrix[n - i - 1, n - j - 1] ^ matrix[n - j - 1, i];
matrix[j, n - i - 1] = matrix[i, j] ^ matrix[j, n - i - 1] ^ matrix[n - i - 1, n - j - 1] ^ matrix[n - j - 1, i];
matrix[n - i - 1, n - j - 1] = matrix[i, j] ^ matrix[j, n - i - 1] ^ matrix[n - i - 1, n - j - 1] ^ matrix[n - j - 1, i];
matrix[n - j - 1, i] = matrix[i, j] ^ matrix[j, n - i - 1] ^ matrix[n - i - 1, n - j - 1] ^ matrix[n - j - 1, i];
matrix[i, j] = matrix[i, j] ^ matrix[j, n - i - 1] ^ matrix[n - i - 1, n - j - 1] ^ matrix[n - j - 1, i];
}
使用異或并不是很直覺,另外一個比較直覺的交換兩個資料的方法是加減法:
a=a+b;
b=a-b;
a=a-b;
我們使用異或而不使用更直覺的加減法是因為a+b的時候可能溢出,那麼接下來的結果就不對了,是以不能用加減法而應該用異或。