大家好,都吃晚飯了嗎?我是Kaiqisan,是一個已經走出社恐的一般生徒,今天第一次更新算法題目,(注,本題來自左神算法)
題目
現有一個矩陣matrix,需要旋轉輸出其中的内容(如圖)

上圖的矩陣輸出為 1 2 3 4 5 10 15 20 19 18 17 16 11 6 7 8 9 14 13 12
方法1
思路
設定一個左上角元素和右下角元素,以這兩個元素為參考點,然後旋轉周遊一圈之後,把這兩個參考點往内縮,再旋轉周遊一周
- 第一周周遊 周遊到第一列第二行後停止。
旋轉列印矩陣java代碼實作 - 左神算法基礎課04 - Kaiqisan方法1方法2總結 - 第二周周遊 參考點變化
旋轉列印矩陣java代碼實作 - 左神算法基礎課04 - Kaiqisan方法1方法2總結
所有點都周遊完成,周遊結束
代碼實作(java)
// 轉圈列印矩陣(順時針)
package Alig2;
public class Demo04circlePrint {
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
// 左上邊界點的坐标
int left = 0;
int top = 0;
// 右下邊界點的坐标
int right = matrix[0].length - 1;
int bottom = matrix.length - 1;
// 一遍疊代表循環輸出列印了一周
while (left <= right && top <= bottom) {
doCirclePrint(matrix, left++, top++, right--, bottom--);
}
}
static void doCirclePrint(int[][] matrix, int left, int top, int right, int bottom) {
// 這裡的意外情況出現在周遊到最内層之後兩個邊界點在行下标或列下标相等的情況
if (left == right && top != bottom) {
for (int i = top; i <= bottom; i++) {
System.out.println(matrix[i][right]);
}
return;
}
if (top == bottom && left != right) {
for (int i = left; i <= right; i++) {
System.out.println(matrix[top][i]);
}
return;
}
if (top == bottom && left == right) {
System.out.println(matrix[left][top]);
}
// 借助參考點旋轉周遊
for (int i = left; i < right; i++) {
System.out.println(matrix[top][i]);
}
for (int i = top; i < bottom; i++) {
System.out.println(matrix[i][right]);
}
for (int i = right; i > left; i--) {
System.out.println(matrix[bottom][i]);
}
for (int i = bottom; i > top; i--) {
System.out.println(matrix[i][left]);
}
}
}
方法2
思路
魔方式旋轉矩陣(前提,矩陣長寬相等)
一次旋轉之後(就像是魔方被扭了一下一樣)
還是需要利用參考點 A (left, top) B(right, bottom)
這個方法和上面的方法類似,隻不過這次是周遊我們要讓矩陣動,不要我們自己周遊的時候去移動
先輸出一次矩陣内容,隻輸出從左上參考點A開始從左往右(對應上面矩陣是 1,2,3,不輸出4是為了防止後面的輸出重疊)
然後開始交換矩陣資料
如圖箭頭所示為交換矩陣内容的方向,
交換一次之後再次輸出(如上第二張圖檔)
一個輪回完成四次,(第一個輪回輸出為 1,2,3,4,8,12,16,15,14,13,9,5)四次完成之後,參考點移動,繼續完成以上的操作,直到所有點都被周遊。
代碼實作
package Alig2;
public class Demo04circlePrint {
public static void main(String[] args) {
int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
int left = 0;
int top = 0;
int right = matrix[0].length - 1;
int bottom = matrix.length - 1;
while (left <= right) {
doCirclePrint(matrix, left++, top++, right--, bottom--);
}
}
static void doSwap(int[][] matrix, int left, int top, int right, int bottom) {
int temp;
for (int i = 0; i < right - left; i++) {
// 元素交換
temp = matrix[left + i][top];
matrix[left + i][top] = matrix[left][bottom - i];
matrix[left][bottom - i] = matrix[right - i][bottom];
matrix[right - i][bottom] = matrix[right][top + i];
matrix[right][top + i] = temp;
}
}
static void doCirclePrint(int[][] matrix, int left, int top, int right, int bottom) {
// 旋轉四次回來,為了還原數組
for (int i = 0; i < 4; i++) {
// 先列印輸出,再旋轉
for (int j = left; j < right; j++) {
System.out.println(matrix[top][j]);
}
doSwap(matrix, left, top, right, bottom);
}
}
}
總結
很重要的知識點,面試高頻題,你還有什麼理由不磨煉!上面給出兩種方法,雖然複雜,但是它們的複雜度較低。