剑指offer19---顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.
int a[][] = {
{1, 2, 3, 4, 5, 6},
{7, 8, 9,10,11,12},
{13,14,15, 16,17,18},
{19,20,21,22,23,24},
{25,26,27.28.29.30},
{31,32,33,34,35,36}};
以从外圈到内圈的顺序依次打印,所以我们可以将这个矩阵看为一圈一圈的。每次打印一圈,然后想办法解决每一圈是如何打印的。
先假设我们实现了一个PrinfMatrixInCircle()函数,可以用来打印这个矩阵的任意一圈,那么接下来我们要做的就是循环来调用这个PrinfMatrixInCircle()函数让它从外圈到内圈的打印。那么接下来就有两个问题:

  1. 打印的起点:最外圈打印的起点当然是左上角的那个点,坐标为(0,0)。然后下一圈呢?很明显,是(2, 2),在下一圈就是(3, 3)。我们发现了规律,每次打印的起点就是 x 坐标和 y 坐标相等的那个点;

  2. 我们可以发现,这个矩阵是6*6的矩阵,它的最内圈的起点坐标为(2, 2),并且,横坐标的2倍小于6,纵坐标的2倍也下于6。接下来,再把内部的矩阵想象为一个单独的矩阵,它是4*4的,它最内圈的起点是(1, 1),并且横坐标的2倍小于4,纵坐标的2倍也小于4。再比如,某个矩阵只有一个点,1*1矩阵,*它最内圈的起点是(0, 0),并且横坐标的2倍小于1,纵坐标的2倍也小于1。假设这个起点坐标为(start,start),则循环继续的条件是
    2*start< rows;2*start< column

public class PrintMatrix {
    public static void main(String[] args) {
        int a[][] = {{1, 2},{ 3, 4},
                {5, 6},{7, 8},
                {9, 10},{ 11, 12},
                {13, 14},{ 15, 16}};
        ArrayList<Integer> result = printMatrix(a);
        for (int i =0;i<result.size();i++){
            System.out.print(result.get(i)+" ");
        }
    }

    public static ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> result = new ArrayList<>();
        if (matrix == null)
            return null;
        int start = 0;
        while (matrix[0].length > start * 2 && matrix.length > start * 2) {
            result.addAll(printOneCircle(matrix, start));
            start++;
        }
        return result;
    }

private static ArrayList<Integer> printOneCircle(int[][] matrix, int start) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        int row = matrix.length;
        int column = matrix[0].length;
        int endX = column-1-start;
        int endY = row -1-start;
        //从左到右打印一行
        for (int i=start;i<=endX;i++){
            arrayList.add(matrix[start][i]);
        }
        //从上到下打印一列;
        for (int i= start+1;i<=endY;i++){
            arrayList.add(matrix[i][endX]);
        }
        //从右到左打印一行;
        if (start<endX && start<endY){
            for (int i = endX-1;i>=start;i--){
                arrayList.add(matrix[endY][i]);
            }
        }
        //从下到上打印一行
        if (start<endX && start<endY-1){
            for (int i= endY-1;i>=start+1;i--){
                arrayList.add(matrix[i][start]);
            }
        }
        return arrayList;
    }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值