本题以逆时针为例
对于这个转换问题的关键是需要明确转换的公式,这里有两个公式可以进行变换,例如对于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度的效果