C 就地矩阵旋转

C 就地矩阵旋转,c,matrix,C,Matrix,我发现了一个有趣的问题,要求将NxN矩阵旋转90度。下面是我用C语言编写的递归解决方案。然而,当我查找其他解决方案时,大多数使用嵌套的for循环来完成任务(这似乎很好)。嵌套循环实现似乎在O(n^2)时间内运行 见: 我相信递归解决方案在O((n^2-n)/2)中运行,也就是O(n^2)。我的问题有两个方面。1) 我上面的复杂性分析对递归和非递归解决方案都正确吗?2)是否有一些高效或聪明的方法来旋转我没有找到的矩阵 蒂亚 #包括 #包括 int SIZE=0; /** *就地、递归、顺时针、9

我发现了一个有趣的问题,要求将NxN矩阵旋转90度。下面是我用C语言编写的递归解决方案。然而,当我查找其他解决方案时,大多数使用嵌套的
for
循环来完成任务(这似乎很好)。嵌套循环实现似乎在
O(n^2)
时间内运行

见:

我相信递归解决方案在
O((n^2-n)/2)
中运行,也就是
O(n^2)
。我的问题有两个方面。1) 我上面的复杂性分析对递归和非递归解决方案都正确吗?2)是否有一些高效或聪明的方法来旋转我没有找到的矩阵

蒂亚

#包括
#包括
int SIZE=0;
/**
*就地、递归、顺时针、90度矩阵旋转。
*/
静态空心旋转到位(int矩阵[][大小],int n)
{
if(n<2)
返回;
int temp1,temp2;
对于(int i=0;i<(n-1);i++)
{
temp1=矩阵[i][n-1];
矩阵[i][n-1]=矩阵[0][i];
temp2=矩阵[n-1][n-i-1];
矩阵[n-1][n-i-1]=temp1;
temp1=矩阵[n-i-1][0];
矩阵[n-i-1][0]=temp2;
矩阵[0][i]=temp1;
}
矩阵=((int*)矩阵)+大小+1;
n-=2;
将_旋转到_位置(矩阵,n);
}
静态无效打印矩阵(整数矩阵[][大小])
{
printf(“\n”);
对于(int i=0;i
旋转不能在少于n^2次的操作中完成,因为需要交换所有元素。但是,通常情况下,由于旋转很难将缓存丢弃,我们会避免执行它;)

您的复杂性分析是正确的,但也非常混乱。由于矩阵中的元素数为n²,因此O(n²)实际上是输入大小的线性时间,这是重要的数字


如果要在旋转后打印整个矩阵,则最好使用线性时间。对于其他操作,最好不要原地旋转矩阵,而是编写一个更改其索引的函数,这样就可以访问旋转矩阵的元素,而无需在内存中进行实际旋转。

就地C解决方案如下

void rotateRight(int matrix[][SIZE], int length) {

    int layer = 0;

    for (int layer = 0; layer < length / 2; ++layer) {

        int first = layer;
        int last = length - 1 - layer;

        for (int i = first; i < last; ++i) {

            int topline = matrix[first][i];
            int rightcol = matrix[i][last];
            int bottomline = matrix[last][length - layer - 1 - i];
            int leftcol = matrix[length - layer - 1 - i][first];

            matrix[first][i] = leftcol;
            matrix[i][last] = topline;
            matrix[last][length - layer - 1 - i] = rightcol;
            matrix[length - layer - 1 - i][first] = bottomline;
        }
    }
}
void rotateRight(整数矩阵[][SIZE],整数长度){
int层=0;
对于(int层=0;层<长度/2;++层){
int first=层;
int last=长度-1-层;
for(int i=第一个;i<最后一个;++i){
int topline=矩阵[第一][i];
int rightcol=矩阵[i][last];
int底线=矩阵[最后一个][长度-层-1-i];
int leftcol=矩阵[length-layer-1-i][first];
矩阵[第一][i]=leftcol;
矩阵[i][last]=背线;
矩阵[最后][长度-层-1-i]=rightcol;
矩阵[长度-层-1-i][first]=底线;
}
}
}

您必须将n*n个元素移动到新的位置,因此很难看出它怎么会小于O(n^2)。我几乎不会将此解决方案称为递归解决方案。你可以用一个
goto
…来代替最后一个调用。这基本上是同一种问题,转置是围绕对角线旋转180度。是的,除了关于对角线元素的注释不适用于旋转,因此在这种情况下可能会产生误导。
void rotateRight(int matrix[][SIZE], int length) {

    int layer = 0;

    for (int layer = 0; layer < length / 2; ++layer) {

        int first = layer;
        int last = length - 1 - layer;

        for (int i = first; i < last; ++i) {

            int topline = matrix[first][i];
            int rightcol = matrix[i][last];
            int bottomline = matrix[last][length - layer - 1 - i];
            int leftcol = matrix[length - layer - 1 - i][first];

            matrix[first][i] = leftcol;
            matrix[i][last] = topline;
            matrix[last][length - layer - 1 - i] = rightcol;
            matrix[length - layer - 1 - i][first] = bottomline;
        }
    }
}