《剑指offer》-顺时针打印矩阵

import java.util.*;
/*
 *输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
 *例如,如果输入如下矩阵: 
 *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.
 */
public class PrintMatrix {
	ArrayList<Integer> list = new ArrayList<Integer>();
	//法一:递归法,定义对角线上两个顶点坐标,递归的终止条件是顶点是否越界
	public ArrayList<Integer> printMatrix(int [][] matrix) {
    	addMatrixElements(0, 0, matrix.length - 1, matrix[0].length - 1, matrix);   
		return list;
	}
	
	public void addMatrixElements(int x1, int y1, int x2, int y2, int [][] matrix) {
		//System.out.println(x1 + " " + y1 + " " + x2 + " " + y2);
		boolean flag1 = false;	//定义三个标志变量,以保证只有当前面一条路径遍历过的时候,才会遍历后面一条路径
		boolean flag2 = false;
		boolean flag3 = false;

		if(y1 > y2 || x1 > x2)	return;
		
		for(int i = y1;i <= y2;i ++) {
			list.add(matrix[x1][i]);
			flag1 = true;
		}
		
		if(flag1) {
			for(int j = x1 + 1;j <= x2;j ++) {
				list.add(matrix[j][y2]);
				flag2 = true;
			}
		}
		
		if(flag2) {
			for(int i = y2 - 1;i >= y1;i --) {
				list.add(matrix[x2][i]);
				flag3 = true;
			}
		}
		
		if(flag3) {
			for(int j = x2 - 1;j > x1;j --) {
				list.add(matrix[j][y1]);
			}
		}
		
		addMatrixElements(x1 + 1, y1 + 1, x2 - 1, y2 - 1, matrix);
	}
	
	//法二:非递归版本,转圈规则
	public ArrayList<Integer> printMatrix2(int [][] matrix) {
    	ArrayList<Integer> list = new ArrayList<Integer>();  
    	int rowLength = matrix.length;
    	int lineLength = matrix[0].length;
    	if(rowLength == 1) {	//是个行向量
    		for(int i = 0,j = 0;j < lineLength;j ++) {
    			list.add(matrix[i][j]);
    		}
    	}
    	else if(lineLength == 1) {	//是个列向量
    		for(int i = 0,j = 0;i < rowLength;i ++) {
    			list.add(matrix[i][j]);
    		}
    	}
    	else list = getArrayList(list, matrix);	//既不是行向量也不是列向量
         
    	return list;
    }
    
    public static ArrayList<Integer> getArrayList(ArrayList<Integer> list, int[][] matrix) {
    	int i = 0;	//定义行起点
    	int j = 0;	//定义列起点
    	int rowLength = matrix.length;	//拿到行的长度
    	int colLength = matrix[0].length;	//拿到列的长度
    	int sum = rowLength * colLength;
    	int count = 0;
    	
    	while(true) {
	    	//一次循环
    		int i2 = i;	//备份初始的行起点
        	int j2 = j; //备份初始的列起点
            
	    	//第一段
        	if(count == sum) break;	//每一次循环之前检查一下是否达到元素总数
			for(;j < colLength;j ++) {
				list.add(matrix[i][j]);
				count ++;
			}
			i ++;
			j --;
			//System.out.println("i:"+i+" j:"+j);
            
			//第二段
        	if(count == sum) break;
			for(;i < rowLength;i ++) {
				list.add(matrix[i][j]);
				count ++;
			}
			j --;
			i --;
            
			//第三段
        	if(count == sum) break;
			for(;j >= j2;j --) {
				list.add(matrix[i][j]);
				count ++;
			}
			i --;
			j ++;
            
			//第四段
        	if(count == sum) break;
			for(;i >= i2 + 1;i --) {
				list.add(matrix[i][j]);
				count ++;
			}
            
			//每一次循环结束之后行起点和列起点各加一
			i = ++ i2;
			if(i >= (matrix.length + 1) / 2)	//如果行起点越过中间位置,就结束循环。这个地方要注意观察奇数阶矩阵和偶数阶矩阵;
				break;
			j = ++ j2;
			rowLength --;
			colLength --;
    	}
		return list;    
    }
	
	public static void main(String[] args) {
		int [][] matrix = new int[1][5];
		int count = 1;
		for(int i = 0;i < matrix.length;i ++) {
			for(int j = 0;j < matrix[0].length;j ++) {
				matrix[i][j] = count ++;
			}
		}
		
		ArrayList<Integer> result = new PrintMatrix().printMatrix(matrix);
		System.out.println(result);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值