数组基操三连(2)

举报
兔老大 发表于 2021/04/22 00:00:57 2021/04/22
【摘要】 转圈打印矩阵 题目: 给定一个整型矩阵matrix,请按照转圈的方式打印它。例如:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,打印结果为:1,2,3,4,5,12,16,15,14,13,9,5,6,7,11,10 要求: 额外空间复杂度为O(1)  思路: 矩阵分圈处理。在矩阵中用左上角的坐标(tR,tC)和右下角的...

转圈打印矩阵


题目:

给定一个整型矩阵matrix,请按照转圈的方式打印它。例如:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,打印结果为:1,2,3,4,5,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)。如果发现左上角坐标跑到右下角坐标的右方或下方,整个过程就停止。已经打印的所有结果连接起来就是我们要求的打印结果。

代码:


  
  1. /**
  2.  * 转圈打印矩阵
  3.  */
  4. public class PrintMatrixSpiralOrder {
  5.     public void spiralOrderPrint(int[][] matrix) {
  6.         int tR = 0;
  7.         int tC = 0;
  8.         int dR = matrix.length - 1;
  9.         int dC = matrix[0].length - 1;
  10.         while (tR <= dR && tC <= dC) {
  11.             printEdge(matrix, tR++, tC++, dR--, dC--);
  12.         }
  13.     }
  14.  
  15.     //转圈打印一个子矩阵的外层,左上角点(tR,tC),右下角点(dR,dC)
  16.     private void printEdge(int[][] matrix, int tR, int tC, int dR, int dC) {
  17.         if (tR == dR) {//子矩阵只有一行时
  18.             for (int i = tC; i <= dC; i++) {
  19.                 System.out.print(matrix[tR][i] + " ");
  20.             }
  21.         } else if (tC == dC) {//子矩阵只有一列时
  22.             for (int i = tR; i <= dR; i++) {
  23.                 System.out.print(matrix[i][tC] + " ");
  24.             }
  25.         } else {//一般情况
  26.             int curCol = tC;
  27.             int curRow = tR;
  28.             while (curCol != dC) {//从左向右
  29.                 System.out.print(matrix[tR][curCol] + " ");
  30.                 curCol++;
  31.             }
  32.             while (curRow != dR) {//从上到下
  33.                 System.out.print(matrix[curRow][dC] + " ");
  34.                 curRow++;
  35.             }
  36.             while (curCol != tC) {//从右到左
  37.                 System.out.print(matrix[dR][curCol] + " ");
  38.                 curCol--;
  39.             }
  40.             while (curRow != tR) {//从下到上
  41.                 System.out.print(matrix[curRow][tC] + " ");
  42.                 curRow--;
  43.             }
  44.         }
  45.     }
  46. }


将正方形矩阵顺时针转动90°


题目:

给定一个N×N的矩阵matrix,把这个矩阵调整成顺时针转动90°后的形式。

例如:

1        2        3        4

5        6        7        8

9        10      11      12

13      14      15      16

顺时针转动90°后为:

13      9       5      1

14      10     6      2

15      11     7      3

16      12     8      4

要求:

额外空间复杂度为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

在这个外圈中,1,4,16,13为一组,然后让1占据4的位置,4占据16的位置,16占据13的位置,13占据1的位置,一组就调整完了。然后2,8,15,9为一组,继续占据调整的过程,最后3,12,14,5为一组,继续占据调整的过程。然后(tR,tC)=(0,0)、(dR,dC)=(3,3)的子矩阵外层就调整完毕,接下来令tR和tC加1,即(tR,tC)=(1,1),令dR和dC减1,即(dR,dC)=(2,2),此时表示的子矩阵如下:

6       7

10     11

这个外层只有一组,就是6,7,11,10,占据调整之后即可。所以,如果子矩阵的大小是M×M,一共就有M-1组,分别进行占据调整即可。

代码:


  
  1. /**
  2.  * 将正方形矩阵顺时针旋转90°
  3.  */
  4. public class RotateMatrix {
  5.     public static void rotate(int[][] matrix) {
  6.         int tR = 0;
  7.         int tC = 0;
  8.         int dR = matrix.length - 1;
  9.         int dC = matrix[0].length - 1;
  10.         while (tR < dR) {
  11.             rotateEdge(matrix, tR++, tC++, dR--, dC--);
  12.         }
  13.     }
  14.  
  15.     private static void rotateEdge(int[][] matrix, int tR, int tC, int dR, int dC) {
  16.         int times = dC - tC;//times就是总的组数
  17.         int temp = 0;
  18.         for (int i = 0; i != times; i++) {//一次循环就是一组占据调整
  19.             temp = matrix[tR][tC + i];
  20.             matrix[tR][tC + i] = matrix[dR - i][tC];
  21.             matrix[dR - i][tC] = matrix[dR][dC - i];
  22.             matrix[dR][dC - i] = matrix[tR - i][dC];
  23.             matrix[tR - i][dC] = temp;
  24.         }
  25.     }
  26. }


“之”字形打印矩阵


题目:

给定一个矩阵matrix,按照“之”字形的方式打印矩阵,例如:

1        2        3        4

5        6        7        8

9        10      11      12

“之”字形打印的结果为:1,2,5,9,6,3,4,7,10,11,8,12

要求:

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

思路;

上坐标(tR,tC)初始化为(0,0),先沿着矩阵第一行移动(tC++),当到达第一行最右边的元素后,在沿着矩阵最后一列移动(tR++)。
下坐标(dR,dC)初始为(0,0),先沿着矩阵第一列移动(dR++),当到达第一列最下边的元素时,再沿着矩阵最后一行移动(dC++)。
上坐标与下坐标同步移动,每次移动后的上坐标与下坐标的连线就是矩阵中的一条斜线,打印斜线上的元素即可。
如果上次斜线是从左下向右上打印的,这次一定是从右上向左下打印,反之亦然。总之,可以把打印的方向用boolean值表示,每次取反即可。
代码:


  
  1. /**
  2.  * 之字形打印矩阵
  3.  */
  4. public class PrintMatrixZigZag {
  5.     public static void printMatrixZigZag(int[][] matrix) {
  6.         int tR = 0;
  7.         int tC = 0;
  8.         int dR = 0;
  9.         int dC = 0;
  10.         int endRow = matrix.length - 1;
  11.         int endCol = matrix[0].length - 1;
  12.         boolean fromUp = false;
  13.         while (tR != endRow + 1) {
  14.             printLevel(matrix, tR, tC, dR, dC, fromUp);
  15.             tR = tC == endCol ? tR + 1 : tR;
  16.             tC = tC == endCol ? tC : tC + 1;
  17.             dR = dR == endRow ? dR : dR + 1;
  18.             dC = dR == endRow ? dC + 1 : dC;
  19.             fromUp = !fromUp;
  20.         }
  21.         System.out.println();
  22.     }
  23.  
  24.     private static void printLevel(int[][] matrix, int tR, int tC, int dR, int dC, boolean fromUp) {
  25.         if (fromUp) {
  26.             while (tR != dR + 1) {//从左下到右上
  27.                 System.out.print(matrix[tR++][tC--] + " ");
  28.             }
  29.         } else {
  30.             while (dR != tR - 1) {//从右上到左下
  31.                 System.out.print(matrix[dR--][dC++] + " ");
  32.             }
  33.         }
  34.     }
  35. }


 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/83381130

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。