数组基操三连(2)
轉圈打印矩陣
題目:
給定一個整型矩陣matrix,請按照轉圈的方式打印它。例如:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,打印結果為:1,2,3,4,5,12,16,15,14,13,9,5,6,7,11,10
要求:
額外空間復雜度為O(1)
?思路:
矩陣分圈處理。在矩陣中用左上角的坐標(tR,tC)和右下角的坐標(dR,dC)就可以表示一個矩陣,比如,題目中的矩陣,當(tR,tC)=(0,0),(dR,dC)=(3,3)時,表示的子矩陣就是整個矩陣,那么這個子矩陣的最外層的部分如下:
1??????????2??????????3??????????4
5??????????????????????????????????8
9?????????????????????????????????12
13???????14????????15????????16
如果能把這個子矩陣的外層轉圈打印出來,那么在(tR,tC)=(0,0)、(dR,dC)=(3,3)時,打印結果為:1,2,3,4,8,12,16,15,14,13,9,5。接下來令tR和tC加1,即(tR,tC)=(1,1),令dR和dC減1,即(dR,dC)=(2,2),此時表示的子矩陣如下:
6????????7
10??????11
再把這個子矩陣轉圈打印出來,結果為:6,7,11,10。把tR和tC加1,即(tR,tC)=(2,2),令dR和dC減1,即(dR,dC)=(1,1)。如果發現左上角坐標跑到右下角坐標的右方或下方,整個過程就停止。已經打印的所有結果連接起來就是我們要求的打印結果。
代碼:
/*** 轉圈打印矩陣*/ public class PrintMatrixSpiralOrder {public void spiralOrderPrint(int[][] matrix) {int tR = 0;int tC = 0;int dR = matrix.length - 1;int dC = matrix[0].length - 1;while (tR <= dR && tC <= dC) {printEdge(matrix, tR++, tC++, dR--, dC--);}}//轉圈打印一個子矩陣的外層,左上角點(tR,tC),右下角點(dR,dC)private void printEdge(int[][] matrix, int tR, int tC, int dR, int dC) {if (tR == dR) {//子矩陣只有一行時for (int i = tC; i <= dC; i++) {System.out.print(matrix[tR][i] + " ");}} else if (tC == dC) {//子矩陣只有一列時for (int i = tR; i <= dR; i++) {System.out.print(matrix[i][tC] + " ");}} else {//一般情況int curCol = tC;int curRow = tR;while (curCol != dC) {//從左向右System.out.print(matrix[tR][curCol] + " ");curCol++;}while (curRow != dR) {//從上到下System.out.print(matrix[curRow][dC] + " ");curRow++;}while (curCol != tC) {//從右到左System.out.print(matrix[dR][curCol] + " ");curCol--;}while (curRow != tR) {//從下到上System.out.print(matrix[curRow][tC] + " ");curRow--;}}} }
將正方形矩陣順時針轉動90°
題目:
給定一個N×N的矩陣matrix,把這個矩陣調整成順時針轉動90°后的形式。
例如:
1????????2????????3????????4
5????????6????????7????????8
9????????10??????11??????12
13??????14??????15??????16
順時針轉動90°后為:
13??????9???????5??????1
14??????10?????6??????2
15??????11?????7??????3
16??????12?????8??????4
要求:
額外空間復雜度為O(1).
思路:
仍然使用分圈處理的方式,
在矩陣中用左上角的坐標(tR,tC)和右下角的坐標(dR,dC)就可以表示一個矩陣,比如,題目中的矩陣,當(tR,tC)=(0,0),(dR,dC)=(3,3)時,表示的子矩陣就是整個矩陣,那么這個子矩陣的最外層的部分如下:
1??????????2??????????3??????????4
5??????????????????????????????????8
9?????????????????????????????????12
13???????14????????15????????16
在這個外圈中,1,4,16,13為一組,然后讓1占據4的位置,4占據16的位置,16占據13的位置,13占據1的位置,一組就調整完了。然后2,8,15,9為一組,繼續占據調整的過程,最后3,12,14,5為一組,繼續占據調整的過程。然后(tR,tC)=(0,0)、(dR,dC)=(3,3)的子矩陣外層就調整完畢,接下來令tR和tC加1,即(tR,tC)=(1,1),令dR和dC減1,即(dR,dC)=(2,2),此時表示的子矩陣如下:
6???????7
10?????11
這個外層只有一組,就是6,7,11,10,占據調整之后即可。所以,如果子矩陣的大小是M×M,一共就有M-1組,分別進行占據調整即可。
代碼:
/*** 將正方形矩陣順時針旋轉90°*/ public class RotateMatrix {public static void rotate(int[][] matrix) {int tR = 0;int tC = 0;int dR = matrix.length - 1;int dC = matrix[0].length - 1;while (tR < dR) {rotateEdge(matrix, tR++, tC++, dR--, dC--);}}private static void rotateEdge(int[][] matrix, int tR, int tC, int dR, int dC) {int times = dC - tC;//times就是總的組數int temp = 0;for (int i = 0; i != times; i++) {//一次循環就是一組占據調整temp = matrix[tR][tC + i];matrix[tR][tC + i] = matrix[dR - i][tC];matrix[dR - i][tC] = matrix[dR][dC - i];matrix[dR][dC - i] = matrix[tR - i][dC];matrix[tR - i][dC] = temp;}} }
“之”字形打印矩陣
題目:
給定一個矩陣matrix,按照“之”字形的方式打印矩陣,例如:
1????????2????????3????????4
5????????6????????7????????8
9????????10??????11??????12
“之”字形打印的結果為:1,2,5,9,6,3,4,7,10,11,8,12
要求:
額外空間復雜度為O(1)
思路;
上坐標(tR,tC)初始化為(0,0),先沿著矩陣第一行移動(tC++),當到達第一行最右邊的元素后,在沿著矩陣最后一列移動(tR++)。
下坐標(dR,dC)初始為(0,0),先沿著矩陣第一列移動(dR++),當到達第一列最下邊的元素時,再沿著矩陣最后一行移動(dC++)。
上坐標與下坐標同步移動,每次移動后的上坐標與下坐標的連線就是矩陣中的一條斜線,打印斜線上的元素即可。
如果上次斜線是從左下向右上打印的,這次一定是從右上向左下打印,反之亦然。總之,可以把打印的方向用boolean值表示,每次取反即可。
代碼:
?
總結
- 上一篇: python基础技巧总结(三)
- 下一篇: 树状数组实现