LeetCode/劍指Offer/順時針打印矩陣
劍指Offer其他題目代碼
【分析】
題目要求逆時針打印全部元素,實際上,數組元素是一圈一圈輸出的。
想到了麗人行裏的小姐姐 ┑( ̄Д  ̄)┍
如果要打印一圈元素的話,就要分上下左右四個部分,分別打印,像這樣:
所有圈都走一遍,就能得到想要的結果,But問題的關鍵在於如何界定每個部分的開始和結束。爲了方便敘述,定義如下變量。
row_begin | 記錄起始行的位置 |
row_end | 記錄結束行的位置 |
col_begin | 記錄開始列的位置 |
col_end | 記錄結束列的位置 |
(i,j) | 應打印元素的下標 |
1.打印上面一行元素時,(i,j)應滿足:
i | row_begin |
j | [col_begin,col_end-1] |
2.打印右面一列元素時,(i,j)應滿足:
i | [row_begin,row_end-1] |
j | col_end |
3.打印下面一行元素時,(i,j)應滿足:
i | row_end |
j | [col_begin+1,col_end] |
4.打印左面一列元素時,(i,j)應滿足:
i | [row_begin+1,row_end] |
j | col_begin |
5.打印完一圈後,重新界定開始和結束的位置:row_begin++;row_end--;col_begin++;col_end--;
然而,事情並沒有結束,我們還需要考慮其他的情況。
最後只剩一行或一列元素:上下或者左右會發生元素重合。記錄已保存的元素個數,個數夠了就結束。
最後只剩一個元素:被漏掉,發生在奇行奇列的數組中。提前將這個元素放到要返回的數組最後。
數組本身就是空的:new一個空的一維數組返回
例子就不舉了......
【代碼】
class Solution {
public static int[] spiralOrder(int[][] matrix) {
//預判數組是否爲空
if(matrix.length==0){
return new int[0];
}
//初始化行首,行尾,列首,列尾
int row_begin = 0;
int row_end = matrix.length - 1;
int col_begin = 0;
int col_end = matrix[0].length - 1;
//定義返回數組
int limit = matrix.length * matrix[0].length;
int[] res = new int[limit];
//對於奇行奇列的二維數組,最後只剩中間的一個元素,將該元素放到res[]的最後
if ((row_end + 1) % 2 == 1 && (col_end + 1) % 2 == 1) {
res[limit - 1] = matrix[(row_end + 1) / 2][(col_end + 1) / 2];
}
int count = -1;
while (row_begin <= row_end && col_begin <= col_end) {
int i = row_begin;//上邊
int j = col_begin;
for (; j <= col_end - 1 && count < limit - 1; j++) {//count是從0開始計算的
res[++count] = matrix[i][j];
}
i = row_begin;
j = col_end;//右邊
for (; i <= row_end - 1 && count < limit - 1; i++) {
res[++count] = matrix[i][j];
}
i = row_end;//下邊
j = col_end;
for (; j >= col_begin + 1 && count < limit - 1; j--) {
res[++count] = matrix[i][j];
}
i = row_end;
j = col_begin;//左邊
for (; i >= row_begin + 1 && count < limit - 1; i--) {
res[++count] = matrix[i][j];
}
//縮小範圍
row_begin++;
row_end--;
col_begin++;
col_end--;
}
return res;
}
}