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;
}
}