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?
二維數組a[n][n]順時針旋轉90度,要解決這個問題,無疑,第一件事兒就是找規律。
當n=1時,不用動了。
當n=2時,
有:
a[0][0] = a[1][0]
a[1][0] = a[1][1]
a[1][1] = a[0][1]
a[0][1] = a[0][0]
在這里我們初步總結規律為:a[i][j] = a[n-1-j][i]
當n=3時,
顯然是滿足上面的規律的
當n=4,5,……時也是滿足的。
到這里,如果不考慮空間復雜的度的話,我們已經可以解決這個問題了,只需要再構建一個二維數組b[n][n],利用公式b[i][j] = a[n-1-j][i],就ok了,代碼如下:
public void rotate(int[][] matrix) { int n = matrix.length; int[][] m = new int[n][n]; for(int row=0;row<n;row++){ for(int col=0;col<n;col++){ m[row][col] = matrix[n-1-col][row]; } } //再賦值回matrix,注意java是形參是引用傳遞 for(int row=0;row<n;row++){ for(int col=0;col<n;col++){ matrix[row][col] = m[row][col]; } } }
但是在這里,題目中也要求了,就在原數組中,應該怎么旋轉?
接着上面的分析,以n=3為例:
我們把焦點放在一個元素的旋轉上,可以看出要在員數組中旋轉,在不丟失數據的情況下,每個值的要旋轉會“波及”4個數,以1為例波及到了1,3,7,9,每個數旋轉要不丟失數據就要考慮如何讓這個4個數都得以保留
前邊總結了規律a[i][j] = a[n-1-j][i],分析每組被波及的數,我們可以得出這里波及的4了數其實就是
a[i][j]
a[n-1-j][i]
a[n-1-i][n-1-j]
a[n-1-(n-1-j)][n-1-i]=a[j][n-1-i]
所以這里需要引入一個臨時變量temp就可以解決這4個數的順時針交換,如:
int temp = matrix[i][j]; matrix[i][j] = matrix[n-1-j][i]; matrix[n-1-j][i] = matrix[n-1-i][n-1-j]; matrix[n-1-i][n-1-j] = matrix[j][n-1-i]; matrix[j][n-1-i] = temp;
把焦點放在一個元素上,數交換的問題解決了,
那么現在我們把焦點回到整個二維數組上來,每個數的旋轉會波及4個數,相當於用上面的方法,每旋轉一個數,就把一組的4個數都旋轉了,
所以現在的問題就是如何才能完整的把所有的數都旋轉90度且不會多旋轉,繼續分析吧,
n=1時,不需旋轉。
n=2時,
只需要完成1(a[0][0])的旋轉,就完成了整個數組的旋轉。
n=3時,
需要完成1,2(a[0][0],a[0][1])的旋轉,就完成了整個數組的旋轉
n=4時,
需要完成1,2,3,6(a[0][0至3],a[1][1])的旋轉
n=5時,
需要完成(a[0][0至4],a[1][1至2])
大致可以總結出這么一個規律:
對於要旋轉的數a[i][j]滿足,
i<n/2
且
i<=j<n-1-i
至此問題終於完美解決了。。
代碼如下:
public class Solution { public void rotate(int[][] matrix) { int n = matrix.length; int limit = (n-1)/2; for(int i=0;i<= limit; i++){ for(int j=i;j<n-1-i;j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[n-1-j][i]; matrix[n-1-j][i] = matrix[n-1-i][n-1-j]; matrix[n-1-i][n-1-j] = matrix[j][n-1-i]; matrix[j][n-1-i] = temp; } } } }