zoukankan      html  css  js  c++  java
  • 数组和矩阵问题:转圈打印矩阵

    题目

         给定一个整型矩阵 matrix, 请按照转圈的方式打印它。

      例如:

      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

    要求

      额外空间复杂度为 O(1)。

    难度

      一星

    解答

      本题在算法上没有什么难度,关键在于设计一种逻辑容易理解、代码易于实现的转圈遍历方式。这里介绍这样一种矩阵处理方式,该方式不仅可用于此题,还适合很多其他的面试题,就是矩阵分圈处理。在矩阵中用左上角的坐标 (tR, tC) 和右下角的坐标 (dR, dC) 就可以表示一个子矩阵,比如,题目中的矩阵,当 (tR, tC) = (0, 0)、(dR, dC) = (3,3) 时,表示子矩阵就是整个矩阵,那么这个子矩阵最外层的部分如下:

      1   2   3  4

      5            8

      9                 12

      13     14     15    16

      如果能把这个矩阵的外层转圈打印出来,那么在(tR, tC) = (0,0)、(dR, dC) = (3,3) 时,打印的结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5。接下来令 tR 和 tC 加 1,即 (tR, tC) = (1,1), 令 dR 和 dC 减 1, 即 (dR, dC) = (2,2), 此时表示的子矩阵如下:

           6    7

      10  11

      再把这个子矩阵转圈打印出来,结果为:6, 7, 11, 10。再令 tR 和 tC 加 1,即(tR, tC) = (2,2), 令 dR 和 dC 减 1, 即 (dR, dC) = (1,1)。如果发现左上角坐标跑到了右下角坐标的右方或者下方,整个过程就停止了。已经打印的所有结果连起来就是我们要求的打印结果。具体请参看如下代码中的 spiralOrderPrint 方法, 其中 printEdge 方法是转圈打印一个子矩阵的外层。

     1 public class Main {
     2     
     3     public static void main(String[] args) {
     4         int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
     5         //1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 
     6         new Main().spiralOrderPrint(matrix);
     7     }
     8     
     9     //打印矩阵
    10     public void spiralOrderPrint(int[][] matrix) {
    11         int tR = 0;
    12         int tC = 0;
    13         int dR = matrix.length - 1;
    14         int dC = matrix[0].length - 1;
    15         while(tR <= dR && tC <= dC){
    16             printEdge(matrix, tR++, tC++, dR--, dC--);
    17         }
    18     }
    19 
    20     //打印子矩阵
    21     public void printEdge(int[][] m, int tR, int tC, int dR, int dC) {
    22         if(tR == dR){ //当子矩阵只有一行时
    23             for(int i = tC; i <= dC; i++){
    24                 System.out.print(m[tR][i] + " ");
    25             }
    26         }else if(tC == dC){ //当子矩阵只有一列时
    27             for(int i = tR; i <= dR; i++){
    28                 System.out.print(m[i][tC] + " ");
    29             }
    30         }else{ //一般情况
    31             int curC = tC;
    32             int curR = tR;
    33             while(curC != dC){ //向右方向
    34                 System.out.print(m[tR][curC++] + " ");
    35             }
    36             while(curR != dR){ //向下方向
    37                 System.out.print(m[curR++][dC] + " ");
    38             }
    39             while(curC != tC){ //向左方向
    40                 System.out.print(m[dR][curC--] + " ");
    41             }
    42             while(curR != tR){ //向上方向
    43                 System.out.print(m[curR--][tC] + " ");
    44             }
    45         }
    46     }
    47     
    48 }
  • 相关阅读:
    关于神奇的MD5算法21
    【转】C# 轻松实现对窗体(Form)换肤
    个人代码库のXML操作演练
    个人代码库の自定义后缀名
    个人代码库の自定义不规则窗体和控件
    个人代码库の创建快捷方式
    jquery 实现省市级联动
    分析器错误消息: 无法识别的属性“targetFramework”。请注意属性名称区分大小写
    EXTJS 面板控件panel应用
    HTTP 错误 500.21 Internal Server Error处理程序
  • 原文地址:https://www.cnblogs.com/zlxyt/p/10514317.html
Copyright © 2011-2022 走看看