受Raymond Chen帖子的启发,假设你有一个4x4二维数组,写一个函数使它旋转90度。Raymond链接到伪代码中的解决方案,但我想看到一些真实的东西。
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
就变成:
[3][9][5][1]
[4][0][6][2]
[5][1][7][3]
[6][2][8][4]
更新:Nick的答案是最直接的,但是有没有比n²更好的方法呢?如果矩阵是10000x10000呢?
受Raymond Chen帖子的启发,假设你有一个4x4二维数组,写一个函数使它旋转90度。Raymond链接到伪代码中的解决方案,但我想看到一些真实的东西。
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
就变成:
[3][9][5][1]
[4][0][6][2]
[5][1][7][3]
[6][2][8][4]
更新:Nick的答案是最直接的,但是有没有比n²更好的方法呢?如果矩阵是10000x10000呢?
当前回答
short normal[4][4] = {{8,4,7,5},{3,4,5,7},{9,5,5,6},{3,3,3,3}};
short rotated[4][4];
for (int r = 0; r < 4; ++r)
{
for (int c = 0; c < 4; ++c)
{
rotated[r][c] = normal[c][3-r];
}
}
简单的c++方法,尽管在大数组中会有很大的内存开销。
其他回答
可以做递归相当干净,这里是我的实现在golang!
在没有额外内存的情况下递归地旋转go golang中的NXN矩阵
func rot90(a [][]int) {
n := len(a)
if n == 1 {
return
}
for i := 0; i < n; i++ {
a[0][i], a[n-1-i][n-1] = a[n-1-i][n-1], a[0][i]
}
rot90(a[1:])
}
这个解决方案不关心正方形或矩形的尺寸,你可以旋转4x5或5x4甚至4x4,它也不关心大小。 注意,这种实现在每次调用rotate90方法时都会创建一个新数组,它根本不会改变原始数组。
public static void main(String[] args) {
int[][] a = new int[][] {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 0, 1, 2 },
{ 3, 4, 5, 6 },
{ 7, 8, 9, 0 }
};
int[][] rotate180 = rotate90(rotate90(a));
print(rotate180);
}
static int[][] rotate90(int[][] a) {
int[][] ret = new int[a[0].length][a.length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
ret[j][a.length - i - 1] = a[i][j];
}
}
return ret;
}
static void print(int[][] array) {
for (int i = 0; i < array.length; i++) {
System.out.print("[");
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]);
System.out.print(" ");
}
System.out.println("]");
}
}
#!/usr/bin/env python
original = [ [1,2,3],
[4,5,6],
[7,8,9] ]
# Rotate matrix 90 degrees...
for i in map(None,*original[::-1]):
print str(i) + '\n'
这导致双方旋转90度(即。123(上面)现在是741(左边)。
这个Python解决方案是可行的,因为它使用了带负步的切片来反转行顺序(将7移到最上面)
original = [ [7,8,9],
[4,5,6],
[1,2,3] ]
然后,它使用map(以及隐含的标识函数,这是map以None作为第一个参数的结果)和*按顺序解包所有元素,重新组合列(即。第一个元素一起放在一个元组中,第二个元素一起放在一个元组中,以此类推)。你有效地得到得到返回如下重组:
original = [[7,8,9],
[4,5,6],
[1,2,3]]
原地旋转不可能比O(n²)更快,原因是如果我们想旋转矩阵,我们必须至少一次触及所有n²元素,无论你实现什么算法。
public static void rotateMatrix(int[,] matrix)
{
//C#, to rotate an N*N matrix in place
int n = matrix.GetLength(0);
int layers = n / 2;
int temp, temp2;
for (int i = 0; i < layers; i++) // for a 5 * 5 matrix, layers will be 2, since at layer three there would be only one element, (2,2), and we do not need to rotate it with itself
{
int offset = 0;
while (offset < n - 2 * i - 1)
{
// top right <- top left
temp = matrix[i + offset, n - i - 1]; //top right value when offset is zero
matrix[i + offset, n - i - 1] = matrix[i, i + offset];
//bottom right <- top right
temp2 = matrix[n - i - 1, n - i - 1 - offset]; //bottom right value when offset is zero
matrix[n - i - 1, n - i - 1 - offset] = temp;
//bottom left <- bottom right
temp = matrix[n - i - 1 - offset, i];
matrix[n - i - 1 - offset, i] = temp2;
//top left <- bottom left
matrix[i, i + offset] = temp;
offset++;
}
}
}