Arrays 如何在不使用任何额外空间的情况下将矩阵旋转90度?
可能重复:Arrays 如何在不使用任何额外空间的情况下将矩阵旋转90度?,arrays,algorithm,Arrays,Algorithm,可能重复: 我所说的90度是指: A = {1,2,3, 4,5,6, 7,8,9} 旋转90度后,A变成: A = {7,4,1, 8,5,2, 9,6,3} 您需要一个temp变量,然后它只是用来跳转元素 temp = A[0]; A[0] = A[6]; A[6] = A[8]; A[8] = A[2]; A[2] = temp; temp = A[1]; A[1] = A[3]; A[3] = A[7]; A[7] = A[5]; A[5]
我所说的90度是指:
A = {1,2,3,
4,5,6,
7,8,9}
旋转90度后,A变成:
A = {7,4,1,
8,5,2,
9,6,3}
您需要一个temp变量,然后它只是用来跳转元素
temp = A[0];
A[0] = A[6];
A[6] = A[8];
A[8] = A[2];
A[2] = temp;
temp = A[1];
A[1] = A[3];
A[3] = A[7];
A[7] = A[5];
A[5] = temp;
换位和交换行或列(取决于要向左还是向右旋转) e。g
所有这些操作都可以在不分配内存的情况下完成。让
a
成为基于nxn数组0的索引
f = floor(n/2)
c = ceil(n/2)
for x = 0 to f - 1
for y = 0 to c - 1
temp = a[x,y]
a[x,y] = a[y,n-1-x]
a[y,n-1-x] = a[n-1-x,n-1-y]
a[n-1-x,n-1-y] = a[n-1-y,x]
a[n-1-y,x] = temp
编辑如果您想避免使用temp,这一次在python中是有效的(它也会以正确的方向旋转)
def rot2(a):
n = len(a)
c = (n+1) / 2
f = n / 2
for x in range(c):
for y in range(f):
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[x][y] ^ a[n-1-y][x]
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[y][n-1-x] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
注意:这只适用于整数矩阵。算法是旋转每个“环”,从最外层到最内层
AAAAA
ABBBA
ABCBA
ABBBA
AAAAA
该算法将首先旋转所有A,然后旋转B,然后旋转C。旋转环需要同时移动4个值
索引i的范围为0..ring-width-1,例如,对于A,宽度为5
(i,0) -> temp
(0, N-i-1) -> (i, 0)
(N-i-1, N-1) -> (0, N-i-1)
(N-1, i) -> (N-i-1, N-1)
temp -> (N-1, i)
然后对每个连续的内圈重复此操作,使坐标偏移,使环宽度减小2
[代码中出现了另一个答案,因此我不再重复。]我遇到了以下实现: 对于平方矩阵:
for n = 0 to N - 2
for m = n + 1 to N - 1
swap A(n,m) with A(m,n)
for each length>1 cycle C of the permutation
pick a starting address s in C
let D = data at s
let x = predecessor of s in the cycle
while x ≠ s
move data from x to successor of x
let x = predecessor of x
move data from D to successor of s
对于矩形矩阵:
for n = 0 to N - 2
for m = n + 1 to N - 1
swap A(n,m) with A(m,n)
for each length>1 cycle C of the permutation
pick a starting address s in C
let D = data at s
let x = predecessor of s in the cycle
while x ≠ s
move data from x to successor of x
let x = predecessor of x
move data from D to successor of s
有关更多信息,请参阅此处:有关就地矩阵转置,请参阅;谷歌也在搜索“就地矩阵变换”。它可以很容易地进行90度旋转。要转换方阵,只需将
b[i][j]
与b[j][i]
交换,其中b[k][l]
是a[n*k+l]
。在非方矩阵上,这要困难得多。“没有任何额外的空间”是一个很强的要求,也许你指的是O(1)空间?(假设整数是固定大小)C++中的实现:。使用上面@Narek描述的方法在C中完成实现
#include <stdio.h>
int n;
unsigned int arr[100][100];
void rotate() {
int i,j,temp;
for(i=0; i<n; i++) {
for(j=i; j<n; j++) {
if(i!=j) {
arr[i][j]^=arr[j][i];
arr[j][i]^=arr[i][j];
arr[i][j]^=arr[j][i];
}
}
}
for(i=0; i<n/2; i++) {
for(j=0; j<n; j++) {
arr[j][i]^=arr[j][n-1-i];
arr[j][n-1-i]^=arr[j][i];
arr[j][i]^=arr[j][n-1-i];
}
}
}
void display(){
int i,j;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("%d",arr[i][j]);}
printf("%s","\n");
}
}
int main(int argc, char *argv[]){
int i,j;
printf("%s","Enter size of matrix:");
scanf("%d",&n);
printf("%s","Enter matrix elements\n");
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
scanf("%d",&arr[i][j]);
}
}
rotate();
display();
return 0;
}
#包括
int n;
无符号整数arr[100][100];
void rotate(){
int i,j,温度;
对于(i=0;数组的大小不是固定的。它可以变化。64x64数组呢?我刚才提到了数组作为一个例子。使用temp不是错误吗?我们不是使用了额外的空间吗?它是一个位置。它与使用x和y、f和c一样错误。如果数组有整数,可以使用xor交换技巧,但仍然需要x和y,至少需要im在讨论算法时,通常不考虑“额外空间”的恒定空间要求。额外的空间通常是整个或部分数据结构的完整副本。此外,我的旋转方向错误,我将很快发布一个更新版本。在python中,我们可以通过执行a,b=b,aNo来交换两个元素,矩阵甚至可以是矩形。您使用的是什么语言?只有方形矩阵可以旋转到位。我们将更改旋转后矩形矩阵的维数,从MxN到NxM,因此在这种情况下我们需要创建一个新的矩阵。该算法将对每个元素进行两次运算。面试官可能会问,是否可以只对元素进行一次运算。@Narek行的大小!=cols的大小???@Narek-hmm。这意味着将有一些固定的init行和列的ial大小总是相反,如果行=3,列=2,那么我们就不能为后代原地旋转:“更改行”意味着“用n行翻转行0,用n-1行翻转行1,等等”。类似于列。如果不是方形NxN矩阵,则很难旋转每个行ring@PeterLee,我不认为旋转非方矩阵是偶数possible@ChanderShivdasani,我同意你的看法。但是如果它是一个方阵,环旋转是一个好主意。@ChanderShivdasani:旋转一个非方阵是可能的。。你只需要将它与其他值一起存储在一个方阵中NULL
你能在每个for循环中用注释补充你的代码吗?@MusséRedi只是用XOR
操作进行交换n^
,没有什么更具体的。首先,在转置时交换。其次,在更改列时。我对实现的更正:您应该从i+1
开始j
,如果(i!=j),则删除
在转置时,您也可以用您描述并链接到矩阵转置的std::swap
替换变换,但OP要求矩阵旋转。