题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解题思路
- 判空:
- 二维数组的判空只有以下几种情况:null,[],[[]];
- 逻辑:
- 获取二维数组的列数和行数;
- 声明2个标识,表明当前读数的方向(上、下、左、右);
- 声明4个变量并初始化,表明本次读数的最大、最小值,即循环结束条件;
- 如果当前正在从左往右读数,则,下次读数的起始位置的纵坐标就要加一,以第一次读第一行为例,因为本次读数已经把第一行最右边的数读了,所以下一次读数要从第二行开始,即min-height++;
- 如果当前正在从上往下读,则,下次读数的起始位置的横坐标要减一,以第一次读最右边的列为例,因为本次读数已经把最后一列最后一行的数读完了,所以下一次读数要从倒数第二行开始,即max-width–;
- 如果当前正在从右往左读,则,下次读数的起始位置的纵坐标要减一,道理同上,即max-height–;
- 如果当前正在从下往上读,则,下次读数的起始位置的横坐标要加一,道理同上,即min-width++;
- 结束当前列(或行)的循环之后,需要改变标识方向的变量,down(right);
- 读取行的循环结束条件为(j < maxWidth && right) || (j >= minWidth && !right);
- 读取列的循环结束条件为(i >= minHeight && !down) || (i < maxHeight && down);
- 最外层循环结束条件是所有的值都已经读完了,返回需要的结果。
代码
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> res = new ArrayList<Integer>();
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return res;
int width = matrix[0].length;
int height = matrix.length;
int minWidth = 0;
int maxWidth = matrix[0].length;
int minHeight = 0;
int maxHeight = matrix.length;
boolean right = true;
boolean down = true;
int count = 0;
int i = 0;
int j = 0;
while(count < (width * height)){
while((j < maxWidth && right) || (j >= minWidth && !right)){
res.add(matrix[i][j]);
count++;
if(right){
j++;
} else {
j--;
}
}
if(right){
++minHeight;
i = minHeight;
// 因为在上面的循环中多加了一次j,所以需要减一
j--;
} else {
--maxHeight;
// maxHeight表示的是数组行数,因此在数组中读数的时候需要减一,获取当前的索引
i = maxHeight-1;
// 因为在上面的循环中多减了一次j,所以需要加一
j++;
}
right = !right;
while((i >= minHeight && !down) || (i < maxHeight && down)){
res.add(matrix[i][j]);
count++;
if(down){
i++;
} else {
i--;
}
}
if(down){
--maxWidth;
// maxWidth表示的是数组列数,因此在数组中读数的时候需要减一,获取当前的索引
j = maxWidth-1;
// 因为在上面的循环中多加了一次j,所以需要减一
i--;
} else {
++minWidth;
j = minWidth;
// 因为在上面的循环中多减了一次j,所以需要加一
i++;
}
down = !down;
}
return res;
}
}