【随想录4 】各种各样打印矩阵的方式

本文参考左老师算法课内容

打印矩阵题比较常见的有以下几道:

59. 螺旋矩阵 II
54. 螺旋矩阵
剑指 Offer 29. 顺时针打印矩阵
48. 旋转图像
之字形打印矩阵

总体来说,做矩阵相关题目时,需要宏观看待整个变化过程。
先多模拟几个用例找到其规律,再开始写代码

59. 螺旋矩阵 II

59. 螺旋矩阵 II


将大矩阵可以看作由一圈圈小矩阵组成,只要逐层将矩阵内的数字填好,那么大矩阵也就填好了。

对于每一圈小矩阵,可以将其分解为四个子矩阵,相当于矩形的四条边。

 			(x1,y1)->-1->-
                    |         |
                    |         |
                    (4)     (2)
                    |         |
                    ⬆️ 		   ⬇️
                    |         |
                     --<-(3)-<--(x2,y2)
class Solution {
    public  int number = 1;
    public  int[][] generateMatrix(int n) {
        int [][]res= new int[n][n];
        int startX=0;
        int startY=0;
        int endX=n-1;
        int endY=n-1;
        while(startX<=endX){
            generate(res,startX++,startY++,endX--,endY--);
        }
        return res;
    }
    private  void generate( int[][] res, int x1, int y1, int x2, int y2 ) {
        //行
        for(int i=y1;i<=y2;i++){
            res[x1][i]=number++;
        }
        //列
        for ( int i =x1+1;i<=x2;i++ ){
            res[i][y2]=number++;
        }
        // 行 《----
        for ( int i = y2-1; i >=y1 ; i-- ) {
            res[x2][i]=number++;
        }
        // 列
        for ( int i = x2-1; i >x1 ; i-- ) {
            res[i][y1]=number++;
        }
    }
}

54. 螺旋矩阵

54. 螺旋矩阵

本题中,需要注意的是,如果只剩一行或者一列,应该要特殊处理,要不然会产生数组越界的bug。

 public List<Integer> list = new ArrayList<>();
    public List<Integer> spiralOrder(int[][] matrix) {
        int m=matrix.length-1;
        int n=matrix[0].length-1;
        int x=0;
        int y=0;
        while ( x<=m && y<=n){
            generate(matrix,x++,y++,m--,n--);
        }
        return list;
    }

        private void generate( int[][] matrix, int x, int y, int m, int n ) {
        if(x==m ){
            for ( int i = y; i <=n ; i++ ) {
                list.add( matrix[x][i] );
            }
        }else if(y==n){
            for ( int i = x; i <=m ; i++ ) {
                list.add( matrix[i][y] );
            }
        }else{
            // 行
            for(int i=y;i<=n;i++){
                list.add( matrix[x][i] );
            }
            //列
            for ( int i = x+1; i <=m ; i++ ) {
                list.add( matrix[i][n] );
            }
            // 行 《--
            for ( int i = n-1; i >=y ; i-- ) {
                list.add( matrix[m][i] );
            }
            // 列
            for ( int i = m-1; i >x; i-- ) {
                list.add( matrix[i][y] );
            }

        }
        
    }

48. 旋转图像

48. 旋转图像

public static void rotate( int[][] matrix ) {
        int x = 0;
        int y = 0;
        int endX = matrix.length - 1;
        int endY = matrix[0].length - 1;
        while ( x < endX ) {
            rotateArr( matrix, x++, y++, endX--, endY-- );
        }
    }


    private static void rotateArr( int[][] matrix, int x, int y, int endX, int endY ) {
        int temp = 0;
        for ( int i = 0; i < endY - y; i++ ) {
            //保存第一行的数
            temp = matrix[x][y + i];
            // 将第一列的数给第一行
            matrix[x][y + i] = matrix[endX - i][y];
            // 将最后一行的数 给第一列
            matrix[endX - i][y] = matrix[endX][endY - i];
            // 将最后一列的数  给最后一行
            matrix[endX][endY - i] = matrix[x + i][endY];
            // 将 第一行的数 给最后一列
            matrix[x + i][endY] = temp;
        }
    }

之字形打印矩阵

之字形打印矩阵

 /*

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

    1,8,6,7

    2,6,4,11

    3,5,9,10

    打印结果是1,8,2,3,6,6,7,4,5,9,11,10。
    要求额外空间复杂度是O(1)。

     */
    public static List<Integer> list = new ArrayList<>();


    private static void printByZ( int[][] arr ) {
        int m = arr.length - 1;
        int n = arr[0].length - 1;
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        // 是否从下往上
        boolean f = true;
        while ( b <= n  ) {
            int printB = a == m ? b++ : b;
            int printA = a == m ? m : a++;
            int printC = d == n ? c++ : c;
            int printD = d == n ? d : d++;
            add( arr, printA, printB, printC, printD, f );
            f = !f;
        }
    }


    private static void add( int[][] arr, int printA, int printB, int printC, int printD, boolean f ) {
        //从下往上
        if ( f == true ) {
            for ( int i = printA; i >= printC; i-- ) {
                list.add( arr[i][printB++] );
            }
        } else {
            for ( int i = printC; i <= printA; i++ ) {
                list.add( arr[i][printD--] );
            }
        }
    }


    public static void main( String[] args ) {
        int[][] arr = new int[][]{
                { 1, 8, 6  }, { 2, 6, 4 }, { 3, 5, 9 }
        };
        printByZ( arr );
        for ( Integer i : list
        ) {
            System.out.printf( "%3d", i );
        }
    }


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值