矩阵处理技巧

矩阵处理技巧

这类技巧用于应对题目要求的奇怪的方式打印矩阵信息。

经典问题

zigzag打印矩阵 转圈打印矩阵 原地旋转正方形矩阵

zigzag打印矩阵

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgVofgii-1663126658375)(/Users/ymy/Library/Application Support/typora-user-images/image-20220913223928925.png)]

以图中红线顺序打印矩阵信息。可以设定两个锚点A,B用于宏观调控轨迹。可以把上述轨迹看成一段段斜线,只需要确定该斜线方向是从上到下还是从下到上打印,打印斜线可以抽象为一个方法,因为打印方向很好确定,就是交替进行。

在这里插入图片描述

A,B两个锚点的运行轨迹如下图,A一直向右,直到到头了再向下移动;B一直向下,直到到头了再向右移动,最终都会到达右下角。

在这里插入图片描述

public static void zigZag(int[][] matrix){
   int endRow = matrix.length - 1, endCol = matrix[0].length - 1;
   boolean topToBottom = false;  // 最开始是从下到上

   int Arow = 0, Acol = 0; // 锚点A
   int Brow = 0, Bcol = 0; // 锚点B

   while (Arow != endRow + 1){
      printLine(matrix, Arow, Acol, Brow, Bcol, topToBottom);
      Arow = Acol == endCol ? Arow + 1 : Arow;
      Acol = Acol == endCol ? Acol : Acol + 1;
      Bcol = Brow == endRow ? Bcol + 1 : Bcol;
      Brow = Brow == endRow ? Brow : Brow + 1;
      topToBottom = !topToBottom;
   }
}

private static void printLine(int[][] matrix, int arow, int acol, int brow, int bcol, boolean topToBottom) {
   if (topToBottom){
      while (arow != brow + 1){
         System.out.print(matrix[arow++][acol--] + "\t");
      }
   } else {
      while (bcol != acol + 1)
         System.out.print(matrix[brow--][bcol++] + "\t");
   }
   System.out.println();
}
旋转打印矩阵

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtHGnj7Z-1663126658376)(/Users/ymy/Library/Application Support/typora-user-images/image-20220914101328988.png)]

以图中红线顺序旋转打印矩阵。首先可以将轨迹拆分成一层一层,再在每层上拆成一段一段。如下两图:
在这里插入图片描述

这种调度方式里,左上角和右下角的点作为锚点来判断轨迹的运行。每一层的起点都是行数+1,列数+1;而每一层的终点都是行数-1,列数-1。绘制一层的时候,有时会遇到两种特殊情况:

1. 只剩下一条水平线的时候
1. 只剩下一条垂直线的时候
public static void Circle(int[][] matrix){
   int startR = 0, startC = 0;
   int endR = matrix.length - 1, endC = matrix[0].length - 1;

   while (startR <= endR && startC <= endC){
      printLayer(matrix, startR++, startC++, endR--, endC--);
      System.out.println();
   }
}

private static void printLayer(int[][] matrix, int startR, int startC, int endR, int endC) {
   if (startR == endR){  // 水平线
      while (startC <= endC)
         System.out.print(matrix[startR][startC++] + "\t");
   } else if (startC == endC) {  // 垂直线
      while (startR <= endR)
         System.out.print(matrix[startR++][startC] + "\t");
   } else { // 正常情况
      int SC = startC, SR = startR;
      while (startC < endC)
         System.out.print(matrix[startR][startC++] + "\t");
      while (startR < endR)
         System.out.print(matrix[startR++][startC] + "\t");
      while (startC > SC)
         System.out.print(matrix[startR][startC--] + "\t");
      while (startR > SR)
         System.out.print(matrix[startR--][startC] + "\t");

   }
}
正方形矩阵的旋转问题

假如有一个方阵,现在要原地进行数据的顺时针旋转90度。原地就是说利用的还是本身这个矩阵空间,不可以开辟新的矩阵空间。示意图如下:

可以将这种变化按圈分割:最外层的元素旋转之后肯定都还在最外层,同样层的元素旋转之后不可能改变层的位置,所以将轨迹变化按层拆解。现在就拿最外层的元素来举例:

该层正方形边长为 4 4 4 ,那么就可以将元素分成 3 3 3组 ,每一组都用不同的记号标注了,相同的记号表示为同一组。每一组的元素只需要按顺时针方向填值即可。

在这里插入图片描述

public static void rotate(int[][] matrix){
   int startR = 0, startC = 0;
   int endR = matrix.length - 1, endC = matrix[0].length - 1;
   while (startR <= endR && startC <= endC)
      rotateLayer(matrix, startR++, startC++, endR--, endC--);
}

private static void rotateLayer(int[][] matrix, int startR, int startC, int endR, int endC) {
   int groups = endC - startC; // 分成的组数
   int tmp = 0;
   for (int i = 0; i < groups; i++) {
      tmp = matrix[startR][startC + i];
      matrix[startR][startC + i] = matrix[endR - i][startC];
      matrix[endR - i][startC] = matrix[endR][endC - i];
      matrix[endR][endC - i] = matrix[startR + i][endC];
      matrix[startR + i][endC] = tmp;
   }
}

核心技巧:找到一种宏观调度方式,不要局限于坐标的变化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值