方阵逆时针旋转

丶灬走出姿态 提交于 2020-03-12 04:51:42

方阵逆时针旋转

今天看到了这样的一道题目,花了一个小时做了一下,用了两种解法,第二种解法空间复杂度为O(1),但思路比较复杂,大家可以一起来讨论一下~

解法一

对于方阵逆时针旋转,很容易想到的就是找出每一个数的规律,复制多一份额外的空间,然后遍历每一个位置,找出其旋转前的位置。

对于下面的方阵,有n = 3
在这里插入图片描述
可以知道旋转后的方阵为
在这里插入图片描述
即有下面变换:
(0,0) <= (0,2)
(1,0) <= (0,1)
(2,0) <= (0,0)…
可以抽象出来(i,j)<= (j,n - 1 - i),代码如下:

void matrixS(int a[length][length])
{
    show(a);
    int b[length][length];
    for (size_t i = 0; i < length; i++)
    {
        for (size_t j = 0; j < length; j++)
        {
            // 两层for循环,遍历方阵每一个数
            b[i][j] = a[j][length - 1 - i];
        }
    }
    printf("旋转后:\n");
    show(b);
}

有测试结果如下:
在这里插入图片描述

解法二

第一种解法时间复杂度O(n),空间复杂度O(n),效率很低,所以有了第二种解法,思路如下:

对于一个n × n 的方阵a,当 n 为偶数时,其外围方圈的层数为 n / 2 ,当 n 为奇数时,除去中心点上的数无需旋转,即有[n / 2]层方圈,[]表示取整,所以无论 n 为奇数还是偶数,我们只需要遍历 n / 2 层,对每一层进行旋转即可。

而对于方阵的每一层方圈 i ,i 属于 [0,n / 2),可以按照四条边分为四个部分,每一个部分均有 n - i * 2 - 1 个数,比如 3 × 3 的方阵最外层有四个部分,每一部分有3 - 0 - 1 = 2 个数,如图:
在这里插入图片描述
可以任取一部分作为基准存储起来,在这里为取第一部分,代码如下:

void matrixS2(int a[length][length])
{
    show(a);
    // 对每一层
    for (size_t i = 0; i < length / 2; i++)
    {
        // 对每一层的四个部分的每一个数
        for (size_t j = 0; j < length - i * 2 - 1; j++)
        {
            // 存储第一部分
            int tmp = a[i + j][i];
            // 将第四部分写到第一部分
            a[i + j][i] = a[i][length - i - j - 1];
            // 将第三部分写到第四部分
            a[i][length - i - j - 1] = a[length - i - j - 1][length - 1 - i];
            // 将第二部分写到第三部分
            a[length - i - j - 1][length - 1 - i] = a[length - 1 - i][j + i];
            // 将第一部分写到第四部分
            a[length - i - 1][i + j] = tmp;
        }
    }
    printf("旋转后:\n");
    show(a);
}

测试结果:
在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!