LeetCode——Rotate Image(二維陣列順時針旋轉90度)
阿新 • • 發佈:2019-02-06
問題:
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時,image旋轉之後變為image有:
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時,image旋轉後變為image。顯然是滿足上面的規律的
當n=4,5,……時也是滿足的。
到這裡,如果不考慮空間複雜的度的話,我們已經可以解決這個問題了,只需要再構建一個二維陣列b[n][n],利用公式b[i][j] = a[n-1-j][i],就ok了,程式碼如下:
但是在這裡,題目中也要求了,就在原陣列中,應該怎麼旋轉? 接著上面的分析,以n=3為例: image旋轉後變為image 我們把焦點放在一個元素的旋轉上,可以看出要在員陣列中旋轉,在不丟失資料的情況下,每個值的要旋轉會“波及”4個數,以1為例波及到了1,3,7,9,每個數旋轉要不丟失資料就要考慮如何讓這個4個數都得以保留 image 前邊總結了規律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 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]; } } }
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; } } } }