剑指offer题18

package jianzhioffer;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,
 * 如果输入如下矩阵: 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 Solution18 {

	//方法一:顺时针打印矩阵 
	/*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) {
		// 从左到右打印一行:终止列号大于起始列号
		for(int i = start;i<columns -start;i++){
			list.add(matrix[start][i]);
		}
		//从上到下打印一列:终止行号大于开始行号
		for(int j = start+1;j<rows-start;j++){
			list.add(matrix[j][columns - start - 1]);
		}
		//从右到左打印一行:终止行号大于起始行号,终止列号大于起始列号
		for(int m = columns -start-2;m>=start&&rows-start-1>start;m--){
			list.add(matrix[rows - start - 1][m]);
		}
		//从下到上打印一列:终止行号至少要比起始行号大2,起始列号小于终止列号
		for(int n = rows - start - 2; n >= start + 1 && columns - start - 1 > start; n--){
			list.add(matrix[n][start]);
		}
		
	}*/
	
	//方法二:
	/*public static ArrayList<Integer> printMatrix(int [][] matrix) {
		ArrayList<Integer> list = new ArrayList<Integer>();
		if(matrix.length == 0) return list;
		int n = matrix.length;
		int m = matrix[0].length;
		if(m == 0) return list;
		int layers = (Math.min(n,m)-1)/2+1; //层数
		for(int i = 0;i<layers;i++){
			for(int k = i;k<m-i;k++)
				list.add(matrix[i][k]);//左至右
			for(int j = i+1;j<n-i;j++)
				list.add(matrix[j][m-i-1]);//右上至右下
			for(int k = m-i-2;(k>=i)&&(n-i-1!=i);k--)
				list.add(matrix[n-i-1][k]);//右至左
			for(int j=n-i-2;(j>i)&&(m-i-1!=i);j--) 
				list.add(matrix[j][i]);//左下至左上
		}
		return list;
	}*/
	
	//方法三:打印第一行,删除第一行,把剩下的元素逆时针转动90度,转置矩阵。重复以上步骤,直到矩阵为空。
		/*//python语句:
		class Solution18:
			def printMatrix(self,matrix):
				ret = []
				while len(matrix) >0:
					ret.extend(matrix[0])
					matrix = zip(*matrix[1:])[::-1]
				return ret
				s = []
				while matrix:
					s+=matrix[0]
					del matrix[0]
					matrix = zip(*matrix)[::-1]
				return s
		 */
	/*static ArrayList<Integer> list = new ArrayList<Integer>();
	public static ArrayList<Integer> printMatrix(int [][] matrix) {
		if(matrix.length<1)
			return list;
		int i = 0;
		for(i=0;i<matrix[0].length;i++){
			list.add(matrix[0][i]);
		}
		if(i>0 && matrix.length -1>0){
			int[][] newarray = new int[i][matrix.length-1];//将3*4变成4行,3-1列
			for(int j = i;j<matrix.length;j++){
				int len = matrix[0].length-1;
				for(int k = len;k>=0;k--){
					newarray[len-k][j-1] = matrix[j][k];
				}
			}
			return printMatrix(newarray);
		}else{
			return list;
		}
	}*/
	//采用旋转魔方的方式,一次取一行,然后旋转
	public static ArrayList<Integer> printMatrix(int[][] matrix) {
		ArrayList<Integer> list = new ArrayList<>();
		int row = matrix.length;
		while(row!=0){
			for(int i = 0; i < matrix[0].length; i++) {
				list.add(matrix[0][i]);
			}
			if(row==1)
				break;
			matrix = turn(matrix);
			row = matrix.length;
		}
		return list;
	}
			
	private static int[][] turn(int[][] matrix) {
		int col = matrix[0].length;
		int row = matrix.length;
		int[][] newMatrix = new int[col][row - 1];
		for (int j = col - 1; j >= 0; j--) {
			for (int i = 1; i < row; i++) {
				newMatrix[col - 1 - j][i - 1] = matrix[i][j];
			}
		}
		return newMatrix;	
	}



	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); //确定矩阵的大小
		int m = sc.nextInt();
		
		int [][] matrix = new int[n][m];
		
		for(int i = 0;i<n;i++){ 
			for(int j = 0;j<m;j++){
				matrix[i][j] = sc.nextInt(); //从控制台得到矩阵的每个元素
			}
		}

		ArrayList<Integer> list = printMatrix(matrix);
		System.out.println(list.toString());
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值