zoukankan      html  css  js  c++  java
  • 剑指offer十九之顺时针打印矩阵

    一、题目

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

     注释:输入的矩阵    

              1     2     3    4

                  5     6     7    8

                  9   10   11   12

                 13  14   15   16

    二、思路

    问题的本质其实就是打印一个方形。每一个方形代表矩阵的每一层。
    但是,打印一个方形,我们必须要知道它的两个对角顶点的位置。有了对角顶点的位置,打印一个方形并不困难了。
    注意:对于一个矩阵,它的长宽可能会不一样,所以,我们需要判断处理。
    两个对角顶点的位置分别为左上角和右下角我们假设矩阵行数是rows,列数是culmns。
    则左上角的位置行标和列标总是相同的,我们取左上角为(start,atart),则右下角为(rows-1,clumns-1)。
    问题的关键在于,怎么确定循环终止条件:
    对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.

    三、代码

    形式1:顺时针遍历 的矩阵存入ArrayList

    import java.util.ArrayList;
    
    public class PrintMatrix {
    
        ArrayList<Integer> arrayList = new ArrayList<Integer>(); //存储顺时针打印的矩阵
    
        //循环打印矩阵
        public ArrayList<Integer> printMatrix(int[][] matrix) {
            int clumns = matrix[0].length;//矩阵的列数
            int rows = matrix.length;//矩阵的行数
            if (matrix == null)//如果为空,返回null
                return null;
    
            int start = 0;//定义矩阵初始元数的序号
    
            while (clumns > 2 * start && rows > 2 * start) {   //对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.
                printMatrixInCircle(matrix, clumns, rows, start);//调用打印一圈的方法
                start++;
            }
            return arrayList;
        }
    
        //打印一圈
        private void printMatrixInCircle(int[][] matrix, int clumns, int rows, int start) {
            int endX = clumns - 1 - start;
            int endY = rows - 1 - start;
            for (int i = start; i <= endX; ++i) {
                int n = matrix[start][i];
                arrayList.add(n);
            }
            //从上到下打印一列
            if (start < endY) {
                for (int j = start + 1; j <= endY; ++j) {
                    int n = matrix[j][endX];
                    arrayList.add(n);
                }
            }
            System.out.println();
            //从右到左打印一行
            if (start < endY && start < endX) {
                for (int k = endX - 1; k >= start; k--) {
                    int n = matrix[endY][k];
                    arrayList.add(n);
                }
            }
            //从下到上打印一列
            if (start < endX && start < endY - 1) {
                for (int l = endY - 1; l > start; l--) {
                    int n = matrix[l][start];
                    arrayList.add(n);
                }
            }
        }
    }
    View Code

    形式2:直接顺时针打印矩阵

    public class PrintMatrix {
        public static void main(String[] args) {
            int[][] num = new int[][]{{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}};
            System.out.println("顺时针打印5x5的矩阵");
            printMatrixClockwisely(num, 5, 5);
            int[][] num2 = new int[][]{{1, 2, 3, 4, 5}};
            System.out.println("顺时针打印1x5的矩阵");
            printMatrixClockwisely(num2, 5, 1);
            int[][] num3 = new int[][]{{1}, {2}, {3}, {4}, {5}};
            System.out.println("顺时针打印5x1的矩阵");
            printMatrixClockwisely(num3, 1, 5);
        }
    
        //循环打印矩阵
        public static void printMatrixClockwisely(int[][] numbers, int clumns, int rows) {
            if (numbers == null || clumns <= 0 || rows <= 0)
                return;
            int start = 0;
            //对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.
            while (clumns > 2 * start && rows > 2 * start) {
                printMatrixInCircle(numbers, clumns, rows, start);
                start++;
            }
        }
    
        //打印一圈
        private static void printMatrixInCircle(int[][] numbers, int clumns, int rows, int start) {
            int endX = clumns - 1 - start;
            int endY = rows - 1 - start;
            //从左到右打印一行
            for (int i = start; i <= endX; ++i) {
                int n = numbers[start][i];
                System.out.print(n + "   ");
            }
            System.out.println();
            //从上到下打印一列
            if (start < endY) {
                for (int j = start + 1; j <= endY; ++j) {
                    int n = numbers[j][endX];
                    System.out.print(n + "   ");
                }
            }
            System.out.println();
            //从右到左打印一行
            if (start < endY && start < endX) {
                for (int k = endX - 1; k >= start; k--) {
                    int n = numbers[endY][k];
                    System.out.print(n + "   ");
                }
            }
            System.out.println();
            //从下到上打印一列
            if (start < endX && start < endY - 1) {
                for (int l = endY - 1; l > start; l--) {
                    int n = numbers[l][start];
                    System.out.print(n + "   ");
                }
            }
            System.out.println();
        }
    }
    View Code

    -------------------------------------------------------------------------------------------------------

    参考链接:

    1、https://www.nowcoder.com/questionTerminal/9b4c81a02cd34f76be2659fa0d54342a

    2、http://blog.163.com/wzz_vie/blog/static/25164906720173106320185/

  • 相关阅读:
    Codeforces Round #706 (Div. 2)
    Caddi Programming Contest 2021(AtCoder Beginner Contest 193)
    [ARC116] Deque Game
    Codeforces Round #721 (Div. 2)
    Codeforces Round #618 (Div. 1)
    Educational Codeforces Round 109 (Rated for Div. 2)
    [ABC201F] Insertion Sort
    AtCoder Regular Contest 119
    Codeforces Global Round 13
    Codeforces Round #673 (Div. 1)
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7620408.html
Copyright © 2011-2022 走看看