矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印

矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印

提示:极其重要的矩阵处理技巧,矩阵下标的宏观调度
重要的矩阵的宏观调度基础知识:
【1】矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码


题目

给你一个矩阵matrix,请你沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印


一、审题

示例:
arr
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20

从外圈,向内圈保卫,顺时针循环打印矩阵
在这里插入图片描述
即1 2 3 4 5 10 15 20 19 18 17 16 11 6 7 8 9 14 13 12


矩阵宏观调度,左上角右下角确定一个矩形环,顺时针打

不妨设矩阵现在就一个外圈,咱们怎么打印这个外圈?
在这里插入图片描述

外圈由左上角a,b点和右下角c,d点确定
上图的绿色外圈就是0 0 点 N-1行,M-1列确定
定义circlePrint(a,b,c,d)函数 打印这个这个外圈

情况很简单,顺时针吗不是?

(1)当b没有碰到d时,b++,沿途打印【图中绿点往右打印】,b碰到d那个点不打印【5】1 2 3 4
(2)当a没有碰到c时,a++,沿途打印【图中橘点往下打印】,a碰到c那个点不打印【20】5 10 15
不妨设原来ab的起始点记着呢,还是ab
(3)当b没有碰到b时,d–,沿途打印【图中粉点往左打印】,d碰到b那个点不打印【16】20 19 18 17
(4)当c没有碰到a时,c–,沿途打印【图中蓝点往上打印】,c碰到a那个点不打印【1】16 11 6
不妨设原来cd的起始点记着呢,还是cd
在这里插入图片描述
外圈打印完成!

我们假设abcd原始都有记忆的
此刻你会发现
只需要将a++,b++,c–,d–
ab点沿着主对角线与cd点沿着主对角线移动一个格子,现在请你开始打印内圈
把abcd四个参数给circlePrint函数,去上面(1)
在这里插入图片描述
另外对于circlePrint函数,下面两点:
注意,可能最开始a=c,就是矩阵的一行,从左往右就打印呗!
在这里插入图片描述
注意,可能最开始b=d,就是矩阵的一列,从上往下就打印呗!
在这里插入图片描述
cirilePrint的代码手撕如下:

    //复习矩阵宏观调度,左上角右下角确定一个矩形环,顺时针打
    //不妨设矩阵现在就一个外圈,咱们怎么打印这个外圈?
    public static void circlePrint(int[][] arr, int a, int b, int c, int d){
        //注意,可能最开始a=c,就是矩阵的一行,从左往右就打印呗!
        if (a == c){
            for (int j = b; j <= d; j++) {
                System.out.print(arr[a][j] +" ");
            }
        }
        //注意,可能最开始b=d,就是矩阵的一列,从上往下就打印呗!
        else if (b == d){
            for (int i = a; i <= c; i++) {
                System.out.print(arr[i][b] +" ");
            }
        }
        //然后才是环打印
        else {
            //(1)当b没有碰到d时,b++,沿途打印【图中绿点往右打印】,b碰到d那个点不打印【5】1 2 3 4
            //用curRow和curColumn来跟abcd,保证abcd不动
            int curRow = a;
            int curColumn = b;
            while (curColumn != d) System.out.print(arr[curRow][curColumn++] +" ");//列往右
            //(2)当a没有碰到c时,a++,沿途打印【图中橘点往下打印】,a碰到c那个点不打印【20】5 10 15
            while (curRow != c) System.out.print(arr[curRow++][curColumn] +" ");//行往下
            //不妨设原来ab的起始点记着呢,还是ab
            //(3)当b没有碰到b时,d--,沿途打印【图中粉点往左打印】,d碰到b那个点不打印【16】20 19 18 17
            while (curColumn != b) System.out.print(arr[curRow][curColumn--] +" ");//列往左
            //(4)当c没有碰到a时,c--,沿途打印【图中蓝点往上打印】,c碰到a那个点不打印【1】16 11 6
            while (curRow != a) System.out.print(arr[curRow--][curColumn] +" ");//行往上
        }
    }

而主函数怎么调用呢?
只要外层宏观调度就是对a<=c && b<=d的所有环,由外到内一次打圈就行
每次ab++,cd–即可
把abcd四个参数给circlePrint函数,去上面(1)

上面已经说过了
在这里插入图片描述
手撕代码如下:

    //而主函数怎么调用呢?
    //只要外层宏观调度就是对a<=c && b<=d的所有环,由外到内一次打圈就行
    //每次ab++,cd--即可
    //把abcd四个参数给circlePrint函数,去上面circlePrint
    public static void matrixCirlcePrint(int[][] arr){
        if (arr == null || arr.length == 0 || arr[0].length == 0) return;

        int a = 0;
        int b = 0;
        int c = arr.length - 1;
        int d = arr[0].length - 1;

        while (a <= c && b <= d) circlePrint(arr, a++, b++, c--, d--);
    }

    public static void test(){
        int[][] arr = {
                {1, 2, 3, 4, 5},
                {6, 7, 8, 9, 10},
                {11,12,13,14,15},
                {16,17,18,19,20}
        };
        //打印出来应该是1, 2, 3, 4, 5 10 15 20 19 18 17 16 11 6 7 8 9 14 13 12

        circleMatrixPrint(arr);
        System.out.println();
        matrixCirlcePrint(arr);
    }

    public static void main(String[] args) {
        test();
    }

结果:

1 2 3 4 5 10 15 20 19 18 17 16 11 6 7 8 9 14 13 12 
1 2 3 4 5 10 15 20 19 18 17 16 11 6 7 8 9 14 13 12 

总结

提示:重要经验:

1)矩阵的操作,往往是有一个很好的宏观调度,要么是AB两点同步走,要么是abcd沿着一圈调度,要么是别的批量调度
2)循环打印矩阵的秘诀在,针对一个外环打印一圈,然后abcd同时收缩,内环继续打印
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值