使用一个额外变量解决”请用最少的额外空间将一个M*N的矩阵旋转90度“

来源:互联网 发布:幕府将军2优化补丁 编辑:程序博客网 时间:2024/06/05 07:35

本题以逆时针为例

对于这个转换问题的关键是需要明确转换的公式,这里有两个公式可以进行变换,例如对于M*N的矩阵A[M][N],旋转后得到B[N][M]

1.按照顺序查看A变换后的位置这种思路可以得到:A[i][j] = B[N - j - 1][i]

2. 按照顺序查看变换后的数值在A中的位置这种思路可以得到:B[i][j] = A[j][N - i - 1]

如果考虑这两点,则可以使用M*N的额外空间申请与之前数组一样大小的空间进行赋值操作即可(对于一维数组可以按照A[i / N][i % N]转换成二维数组操作)

#include <stdio.h>
#define M 5
#define N 10
int main(){
    int test[M*N];
    int temp[M * N]; 
    int i = 0, k = 0;
    for(i = 0; i < M * N; i++){
        test[i] = i;
        if (i % N == 0)
            printf("\n");
        printf("%10d", test[i]);
    }   
    
    printf("\n a M*N memory exchange:\n");
    for(i = 0; i < M * N; i++){
        //temp[(N - i % N - 1) * M + i / N] = test[i]; 
        temp[i] = (i % M) * N + N - i / M - 1;
    }   
    for(i = 0; i < M * N; i++){
        if (i % M == 0)
            printf("\n");
        printf("%10d", temp[i]);
    }   
    printf("\n");

}


但是这样的额外空间为M*N,肯定不是理想的情况;

基于上面的实现,我们可以考虑是否可以在赋值时,将赋值操作变换成互换操作,这样就可以使用一个额外空间

但是如果变为互换又会出现新的问题,即互换以后如何能够在接下来需要这个数据时正确索引;

通过分析,我们可以发现,如果按照旋转之后的顺序进行存储时,如果与当前位置互换的位置大于目前操作的位置,则互换位置没有被更新过,直接互换就行;反之,则被之前的互换操作替换过,而替换到的位置就是互换的公式位置,这样继续查找直到找到大于目前操作的位置,然后将此位置的数据与当前位置的数据进行互换;

   for(i = 0; i < M * N; i++){
        k = (i % M) * N + N - i / M - 1;
        while(k < i){ 
            k = (k % M) * N + N - k / M - 1;
        }   
        value = test[i];
        test[i] = test[k];
        test[k] = value;
    }   

这样就实现了只使用一个额外空间就达到矩阵旋转90度的效果

原创粉丝点击