【Offer】[29] 【顺时针打印矩阵】

题目描述

  输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 例如,如果输入如下矩阵:
  

  则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。

牛客网刷题地址

思路分析

将矩阵看成若干个顺时针方向的圈组成.

  1. 第一步:接下来分析循环结束的条件。假设这个矩阵的行数是rows,列数是columns。打印第-圈的左上角的坐标是(0, 0),第二圈的左上角的坐标是(1, 1),以此类推。我们注意到,左上角的坐标中行标和列标总是相同的,于是可以在矩阵中选取左上角为(start, start)的一圈作 为我们分析的目标。对于一个5X5的矩阵而言,最后一-圈只有一个数字,对应的坐标为(2, 2)。我们发现5> 2x2。对于一个6X6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2, 2)。 我们发现6>2*2依然成立。于是可以得出,让循环继续的条件是columns > startXx2并且rows > startY*2。
  2. 第二步:如何打印一圈的矩阵:
    我们可以分为四步:从左到右,从上到下,从右到左,从下到上,但是打印一圈时会出现如下特殊情况:所以说,这四步并不是都要执行

可以将其想象为一个原点在左上角的(X,Y)坐标轴,来进行分析。

测试用例

  1. 数组中有多行多列;数组中只有一行;数组中只有一列;数组中只一行一列。

Java代码

public class Offer29 {
    public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    public static ArrayList<Integer> printMatrix(int[][] matrix) {
        return Solution1(matrix);
    }

    private static ArrayList<Integer> Solution1(int[][] matrix) {
        if (matrix == null || matrix.length <= 0 || matrix[0].length <= 0) {
            return null;
        }
        int start = 0;
        int rows = matrix.length;
        int columns = matrix[0].length;

        ArrayList<Integer> listSum = new ArrayList<Integer>();

        while (columns > start * 2 && rows > start * 2) {
            ArrayList<Integer> list = printMatrix(matrix, rows, columns, start);
            listSum.addAll(list);
            ++start;
        }

        return listSum;
    }

    public static ArrayList<Integer> printMatrix(int[][] matrix, int rows, int columns, int start) {
        int endX = columns - 1 - start;// 横坐标
        int endY = rows - 1 - start;// 竖坐标
        ArrayList<Integer> list = new ArrayList<Integer>();
        // 左到右打印
        for (int i = start; i <= endX; i++) {
            int num = matrix[start][i];
            System.out.println(num + ",");
            list.add(num);
        }

        // 从上到下打印
        if (start < endY) {
            for (int j = start + 1; j <= endY; j++) {
                int num = matrix[j][endX];
                System.out.println(num + ",");
                list.add(num);
            }
        }

        // 从右到左打印
        if (start < endX && start < endY) {
            for (int i = endX - 1; i >= start; i--) {
                int num = matrix[endY][i];
                System.out.println(num);
                list.add(num);
            }
        }
        // 从下往上打印
        if (start < endX && start + 1 < endY) {
            for (int j = endY - 1; j >= start + 1; j--) {
                int num = matrix[j][start];
                System.out.print(num + ",");
                list.add(num);
            }
        }

        return list;

    }

    private static void test1() {}
    private static void test2() {}
    private static void test3() {}

}

代码链接

剑指Offer代码-Java

原文地址:https://www.cnblogs.com/haoworld/p/offer29-shun-shi-zhen-da-yin-ju-zhen.html