题目大意
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
分析
可以将打印矩阵分为,打印矩阵的每一圈。打印总是从(start,start)位置开始。首先我们要明白如何确定每一圈的起始位置,也就是明确start的取值范围。

image.png

image.png
举例分析,假设输入矩阵大小为rows * cols. 则start需要符合start * 2<rows && start*2<cols。

image.png
输出每一圈矩阵数字,可以分为四个步骤。如上图所示,步骤1不需要条件判断,而步骤2-4都需要条件的筛选。
- 往右走。for(int i=start;i<=endX;i++)
- 往下走。if(start < endY)
- 往左走。if(start<endY && start < endX)
- 往上走。if(start<endY-1 && start<endX)
代码
首先来看最外层的代码,输出矩阵每一圈的函数在 printCircle中。
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> res = new ArrayList<>();
if(matrix == null || matrix.length == 0) return res;
int rows = matrix.length;
int cols = matrix[0].length;
for(int start = 0;start*2<rows && start*2<cols ;++start)
printCircle(matrix,start,res);
return res;
}
private void printCircle(int[][] matrix,int start,ArrayList<Integer>res) {
int cols = matrix[0].length;
int rows = matrix.length;
int endX = cols-start-1;
int endY = rows-start-1;
//四种情况
//1.先向右边走,这一步一定会发生
for(int i=start;i<=endX;i++) {
res.add(matrix[start][i]);
System.out.print(matrix[start][i]+" ");
}
//2. 往下走
if(start < endY) {
for(int i = start+1;i<=endY;i++) {
res.add(matrix[i][endX]);
System.out.print(matrix[i][endX]+" ");
}
}
//3. 往左走
if(start<endY && start < endX) {
for(int i = endX-1;i>=start;--i) {
res.add(matrix[endY][i]);
System.out.print(matrix[endY][i]+" ");
}
}
// 4. 向上走
if(start<endY-1 && start<endX) {
for(int i=endY-1;i>=start+1;--i) {
res.add(matrix[i][start]);
System.out.print(matrix[i][start]+" ");
}
}
}