题目:输入一个矩阵,按照从外向里以顺时针顺序依次打印出每一个数字
分析:可以把矩阵想象为若干个圈,用一个循环来打印矩阵,每次打印矩阵中的一个圈,如左图。设矩阵行rows,列是columns,打印第一圈左上角坐标是(0,0),第二圈左上角坐标是(1,1),以此类推注意到左上角的坐标中行标和列标总是相同的,选择矩阵中左上角(start,start)的一圈作为分析目标发现,循环继续的条件是columns>startX*2且rows>startY*2.
如何打印一圈,分为四步,即:1.从左到右打印一行;2.从上到下打印一列;3.从右到左打印一行;4.从下到上打印一列,注意的是最后一圈可能退化为只有一行、只有一列或只有一个数字,如右图所示,根据打印时每一步的前提条件,即可分析写出循环,代码如下
import java.util.*;
public class wr20printMatrix {
static ArrayList<Integer> list=new ArrayList<>();
public static ArrayList<Integer> printMatrix(int [][]matrix){
int rows=matrix.length;//行
int columns=matrix[0].length;//列
int start=0;
while(rows>start*2 && columns>start*2){
printMatrixInCircle(matrix,rows,columns,start);
start++;
}
return list;
}
public static void printMatrixInCircle(int [][]matrix,int rows,int columns,int start){
int endRow=columns-start-1;//一行到尾部,表示列数
int endColumns=rows-start-1;//一列到尾部,有几行
// 1.从左到右打印一行
// 打印一圈至少要一步
for(int i=start;i<=endRow;i++){
list.add(matrix[start][i]);
}
// 2.从上到下打印一列
// 需要第二步前提是,终止行号大于起始行号
if(start<endColumns){
for(int i=start+1;i<=endColumns;i++){
list.add(matrix[i][endRow]);
}
}
// 3.从右到左打印一行
// 需要第三步前提是,圈内至少有两行两列,即终止行号大于起始行号且终止列号大于起始列号
if(start<endRow && start<endColumns){
for(int i=endRow-1;i>=start;i--){
list.add(matrix[endColumns][i]);
}
}
// 4.从下到上打印一列
// 需要第四步前提是至少有三行两列,即终止行号比起始行号大2且终止列号大于起始列号
if(start<endColumns-1 && start<endRow){
for(int i=endColumns-1;i>=start+1;i--){
list.add(matrix[i][start]);
}
}
}
public static void main(String []args){
int [][]array={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
ArrayList<Integer> result=printMatrix(array);
for(int i:result){
System.out.print(i+" ");
}
}
}