用用最小空间度将一个M*N的矩阵旋转90度(顺逆时针均可)

行业问题 逆时针,矩阵,最小 已帮助 人

用用最小空间度将一个M*N的矩阵旋转90度(顺逆时针均可)

热搜:n阶方阵a与对角矩阵相似的充要条件

答案解析

难度★★☆ 搜索
  • 正确答案:

    算法说明:
    设有一个(M×N)3*4维矩阵A,旋转后成4*3
    1 2 3 4 9 5 1
    5 6 7 8 => 10 6 2
    9 10 11 12 11 7 3
    12 8 4
    可以发现旋转后矩阵与原矩阵的关系:
    旋转后 原矩阵
    A[0,0] = A[2,0] = 9
    A[0,1] = A[1,0] = 5
    A[0,2] = A[0,0] = 1
    A[1,0] = A[2,1] = 10
    A[1,1] = A[1,1] = 6
    A[1,2] = A[0,1] = 2
    A[2,0] = A[2,2] = 11
    A[2,1] = A[1,2] = 7
    A[2,2] = A[0,2] = 3
    A[3,0] = A[2,3] = 12
    A[3,1] = A[1,3] = 8
    A[3,2] = A[0,3] = 4
    可以得出对应关系为:旋转后矩阵A[i,j] = 原矩阵A[ M- j -1, i ]
    所以我们可以用同一个矩阵来保存转换前后的值
    用两层循环(注意外层为N,内层为M),
    依次交换A[i,j] 与 A[ M- j -1, i ],
    (交换不用额外存储空间,直接相加交换,如交换a和b的值:a= a+ b; b= a- b; a = a - b)
    这样可以求出A[i,j]的值,原来A[i,j]的值则保存在A[ M- j -1, i ]中
    每一个A[i,j]都唯一对应一个A[ M- j -1, i ],所以我们从0开始依次求A[i,j]的值
    要注意的是如果A[ M- j- 1 ,i]在数组中存放的位置在A[i,j]之后,我们才做交换
    如果A[ M- j- 1 ,i]在A[i,j]之前,则说明A[ M- j- 1 ,i]已经交换过,其值存在对应的
    次A中,依次查找,直到找到位于A这后的对应元素即为该交换的值,下面用流程说明

    ~A[x,y]表示A[i,j]对应在原矩阵中的元素.
    处理元素A[0,0](在数组中的位置为0), 其对应原矩阵的~A[2,0](对应位置为8),交换
    处理元素A[0,1](位置为1),~A[1,0](位置为4),交换
    处理元素A[0,2](位置为2),~A[0,0](位置为0),不交换,
    查找到位置为0的元素对应的~~A[2,0](位置为8),在其之后,即A[2,0]与A[0,0]交换过
    直接交换A[0,2]和A[2,0] 转摘请注明:http://www.pghome.net/
    依此类推。
    A[1,0](位置3) -> ~A[2,1](位置9)
    A[1,1](位置4) -> ~A[1,1](位置6)
    A[1,2](位置5) -> ~A[0,1](位置1)(交换过) -> ~~A[2,1] = A[1,0]
    ...
    A[3,2](位置11) -> ~A[0,3](位置2,对应新矩阵下标[1,0])(交换过)
    -> ~~A[2,1](位置9) ...... ~~~~A[2,3] = 4
    为便于理解,可画出下面三个矩阵。
    原矩阵 (存储方式相同的矩阵) 旋转后
    1 2 3 4 1 2 3 9 5 1
    5 6 7 8 => 4 5 6 => 10 6 2
    9 10 11 12 7 8 9 11 7 3
    10 11 12 12 8 4

    #include <stdio.h>
    #include<conio.h>

    const int M=3;
    const int N=4;
    main()
    {
    int Matrix[M][N]={1,2,3,4,5,6,7,8,9,10,11,12};
    int i=0 ;
    int j=0 ;
    int tmpi = 0;
    int tmpj = 0;
    int u = 0;
    printf("原矩阵为:");
    for (i= 0 ;i< M ;i++)
    {
    for(j=0 ; j< N; j++)
    printf(" %d ",Matrix[i][j]);
    printf("");
    }
    printf("顺时针转90度后:");
    for (i= 0 ;i< N ; i++)
    {
    for(j= 0 ; j< M; j++)
    {
    求该交换元素在原矩阵对应的位置
    tmpi = M- j -1;
    tmpj = i ;
    循环查找最后交换的位置
    while((tmpi * N + tmpj) < i * M + j )
    {
    u= (tmpi * N + tmpj );
    tmpi = u / M ;
    tmpj = u % M ;

    tmpi = tmpi + tmpj;
    tmpj = tmpi - tmpj;
    tmpi = tmpi - tmpj;
    tmpi = (M-tmpi -1);
    }
    交换矩元素,后一个作暂存用
    if (*(&Matrix[0][0] + i * M + j) != Matrix[tmpi][tmpj])
    {
    *(&Matrix[0][0] + i * M + j) = *(&Matrix[0][0] + i * M + j)
    + Matrix[tmpi][tmpj];
    Matrix[tmpi][tmpj] = *(&Matrix[0][0] + i * M + j)
    - Matrix[tmpi][tmpj];
    *(&Matrix[0][0] + i * M + j) = *(&Matrix[0][0] + i * M + j)
    - Matrix[tmpi][tmpj];
    }

    printf(" %d ",*(&Matrix[0][0] + i * M + j));
    }
    printf("");
    }
    getch();
    return 0;
    }