矩阵宏观调度:将正方形矩阵原地顺时针旋转90°度

矩阵宏观调度:将正方形矩阵原地顺时针旋转90°度

提示:极其重要的矩阵处理技巧,矩阵下标的宏观调度
重要的矩阵的宏观调度基础知识:
【1】矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码
【2】矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印


题目

矩阵宏观调度:将正方形矩阵原地顺时针旋转90°度


一、审题

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

沿着下面矩阵中心+顺时针旋转90°,变成
在这里插入图片描述


矩阵宏观调度,外圈向内圈,一批一批旋转,替代

单看外圈,下图绿点
定义一个循环旋转函数circleRotate(a,b,c,d):
ab=00,cd=N-1,M-1确定了这外圈
(1)让tmp记录橘色这段
(2)让粉色段过来替代橘色段
(3)让红色段过来替代粉色段
(4)让蓝色段过来替换红色段
(5)让tmp替代蓝色段
岂不就完成了顺时针旋转90°?
简单吧
在这里插入图片描述

【2】矩阵宏观调度:沿着矩阵matrix的四周一圈一圈由外层,向内层顺时针循环打印
一样,若是此刻,将ab++,cd–,就进入内圈,继续调用(1)循环旋转
在这里插入图片描述
这样整体就旋转完成了
切记a<c,b<d,如果a=c,b=d那就是一个点
一个点不用旋转了,下图5数字,外圈转完,ab++,cd–,a=c,b=d就一个数,怎么旋转还是它!
在这里插入图片描述

我们来看细节:
循环旋转函数circleRotate(a,b,c,d):
ab=00,cd=N-1,M-1确定了这外圈

其实每一批,旋转多少个数呢?d-b个数,比如下面d=3,b=0,d-b=3个
下标就是0 1 2 就0–d-b-1
所以替代的话,咱们下标从i=0–d-b-1,一个一个替换,跟交换函数一样
在这里插入图片描述
手撕代码如下:

   //复习旋转
    //循环旋转函数**circleRotate(a,b,c,d):**
    public static void circleRotate(int[][] arr, int a, int b, int c, int d){
        //ab,cd=确定了这外圈
        //其实每一批,旋转多少个数呢?d-b个数,比如下面d=3,b=0,d-b=3个
        for (int i = 0; i < d - b; i++) {
            //下标就是0 1 2 就0--d-b-1
            //所以替代的话,咱们下标从i=0--d-b-1,一个一个替换,跟交换函数一样
            int tmp = arr[a][b + i];//记忆橘色这一行,从左往右
            arr[a][b + i] = arr[c - i][b];//搬粉色b那列,c从下往上
            arr[c - i][b] = arr[c][d - i];//搬红色c那行,d从右往左
            arr[c][d - i] = arr[a + i][d];//搬蓝色d那列,a从上往下
            arr[a + i][d] = tmp;//搬记忆的橘色a这一行,b从左往右
        }
        //最重要的就是下标控制,走向
    }

整个矩阵的调度:
最开始ab=00,cd=N-1,M-1确定了这外圈,外圈旋转完,将ab++,cd–,就进入内圈,继续调用circleRotate函数循环旋转

   //最开始ab=00,cd=N-1,M-1确定了这外圈,外圈旋转完,
    // 将ab++,cd--,就进入内圈,继续调用circleRotate函数循环旋转
    public static void rotateMatrixReview(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) circleRotate(arr, a++, b++, c--, d--);
    }

    public static void test(){
        int[][] arr = {
                {1, 2, 3, 4},
                {6, 7, 8, 9},
                {11,12,13,14},
                {16,17,18,19}
        };
        int[][] arr2 = {
                {1, 2, 3, 4},
                {6, 7, 8, 9},
                {11,12,13,14},
                {16,17,18,19}
        };
        //旋转完以后
//        {16, 11, 6, 1},
//        {17, 12, 7, 2},
//        {18, 13, 8, 3},
//        {19, 14, 9, 4}
        rotateMatrixPrint(arr);
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[0].length; j++) {
                System.out.print(arr[i][j] +" ");
            }
            System.out.println();
        }

        System.out.println();
        rotateMatrixReview(arr2);
        for (int i = 0; i < arr2.length; i++) {
            for (int j = 0; j < arr2[0].length; j++) {
                System.out.print(arr2[i][j] +" ");
            }
            System.out.println();
        }
    }

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

测试一把:

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

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

总结

提示:重要经验:

1)矩阵的宏观调度,非常有趣,按照AB点同步走,或者abcd固定外圈,一批一批数据调度完,往内继续循环调度
2)本题的关键,就在先tmp记录一批数据,拿另一批数据旋转过来覆盖,abcd固定不动,从一个方向到一个方向一个个搬移,下标要搞清楚
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰露可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值