題目描述:
對于一個矩陣,請設計一個算法從左上角(mat[0][0])開始,順時針列印矩陣元素。
給定int矩陣mat,以及它的維數nxm,請傳回一個數組,數組中的元素為矩陣元素的順時針輸出。
測試樣例:
[[1,2],[3,4]],2,2
傳回:[1,2,4,3]
解題思路:
對于一個矩陣,順時針列印時一定要保證邊界處理的正确性;
解題代碼:
public class Printer {
public int[] clockwisePrint(int[][] mat, int n, int m) {
// write code here
// 定義一個傳回結果的數組,将順時針周遊的所有值存下來傳回
int[] ret = new int[m*n]; // n為行,m為列
// 判斷非法輸入的情況
if(n <= 0 || m <= 0)
return ret;
// 定義控制行的下标
int i = 0;
// 定義控制列的下标
int j = 0;
// 定義控制要傳回的數組ret的下标
int index = 0;
// 定義圈數,每周遊完一層就 +1
int N = 0;
// 當要傳回的數組的下标超過 n*m 時,說明數組已經滿了,也就是給定的mat數組中所有的數都已
//經周遊完了,此時結束
while(index < ret.length) {
// 向右列印,列++,行不動,列 < 總列數-圈數,可以有效的控制列印的列下标
while(j < m-N && index < ret.length) {
ret[index] = mat[i][j];
index++;
j++;
}
// 向下列印
// 要豎着列印的第一個元素上一個橫着向右列印已經周遊過了,是以 i++,來到下一行
i++;
// 由于上面的橫着向右列印最後結束的位置在 mat[i][m - N],這裡已經越界,是以要進行j--
j--;
// 行++,列不動,行 < 總行數-圈數
while(i < n-N && index < ret.length) {
ret[index] = mat[i][j];
index++;
i++;
}
// 向左列印
j--;
i--;
// j >= N 和上面的道理是一樣的,可以帶個值進行驗證一下,比第一圈(N = 0), 是以向左
//周遊要到第一列(下标是0)的位置
while(j >= N && index < ret.length) {
ret[index] = mat[i][j];
j--;
index++;
}
// 向上列印
j++;
i--;
// 注意這裡沒有等号,比如 第一圈(N = 0),第一行(下标為0)的位置已經列印過了
while(i > N && index < ret.length) {
ret[index] = mat[i][j];
i--;
index++;
}
// 一圈已經周遊完了,就來到下一圈
N++;
// 行和列的下标都要 +1,往裡走一圈
i++;
j++;
}
// 傳回結果
return ret;
}
}