剑指offer--20.顺时针打印矩阵

题目:输入一个矩阵,按照从外向里以顺时针顺序依次打印出每一个数字

分析:可以把矩阵想象为若干个圈,用一个循环来打印矩阵,每次打印矩阵中的一个圈,如左图。设矩阵行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+" ");
		}
	}

}

猜你喜欢

转载自blog.csdn.net/autumn03/article/details/80180753