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/

  • 相关阅读:
    阿里DatatX mysql8往 Elasticsearch 7 插入时间数据 时区引发的问题
    通俗易懂 k8s (3):kubernetes 服务的注册与发现
    ReplicaSet 和 ReplicationController 的区别
    使用Go module导入本地包
    k8s之statefulset控制器
    终于成功部署 Kubernetes HPA 基于 QPS 进行自动伸缩
    Atitit drmmr outline org stat vb u33.docx Atitit drmmr outline org stat v0 taf.docx Atitit drmmr out
    Atitit all diary index va u33 #alldiary.docx Atitit alldiaryindex v1 t717 目录 1. Fix 1 2. Diary deta
    Atitit path query 路径查询语言 数据检索语言 目录 1.1. List map >> spel 1 1.2. Html数据 》》Css选择符 1 1.3. Json 》map》
    Atitit prgrmlan topic--express lan QL query lan表达式语言 目录 1. 通用表达语言(CEL) 1 1.1. 8.2 功能概述 1 1.2. Ongl
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7620408.html
Copyright © 2011-2022 走看看