天天看點

記一道有意思的算法題Rotate Image(旋轉圖像)

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的時候可能溢出,那麼接下來的結果就不對了,是以不能用加減法而應該用異或。

繼續閱讀