受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呢?
当前回答
这里有大量的好代码,但我只是想以几何形式展示,这样你就能更好地理解代码逻辑。以下是我的处理方法。
首先,不要把这和换位相混淆,换位是很容易的。
基本的想法是把它当作层,我们一次旋转一个层。
假设我们有一辆4x4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
当我们顺时针旋转90度,我们得到
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
我们来分解它,首先旋转这四个角
1 4
13 16
然后我们旋转下面这个有点歪斜的菱形
2
8
9
15
然后是第二个斜菱形
3
5
12
14
这就搞定了外缘基本上我们一次做一个壳层直到
最后是中间的方块(如果是奇数则是最后一个不动的元素)
6 7
10 11
现在我们来算出每一层的指标,假设我们总是在最外层工作,我们正在做
[0,0] -> [0,n-1], [0,n-1] -> [n-1,n-1], [n-1,n-1] -> [n-1,0], and [n-1,0] -> [0,0]
[0,1] -> [1,n-1], [1,n-2] -> [n-1,n-2], [n-1,n-2] -> [n-2,0], and [n-2,0] -> [0,1]
[0,2] -> [2,n-2], [2,n-2] -> [n-1,n-3], [n-1,n-3] -> [n-3,0], and [n-3,0] -> [0,2]
等等等等 直到我们走到边缘的一半
所以总的来说模式是
[0,i] -> [i,n-i], [i,n-i] -> [n-1,n-(i+1)], [n-1,n-(i+1)] -> [n-(i+1),0], and [n-(i+1),0] to [0,i]
其他回答
/* 90-degree clockwise:
temp_array = left_col
left_col = bottom_row
bottom_row = reverse(right_col)
reverse(right_col) = reverse(top_row)
reverse(top_row) = temp_array
*/
void RotateClockwise90(int ** arr, int lo, int hi) {
if (lo >= hi)
return;
for (int i=lo; i<hi; i++) {
int j = lo+hi-i;
int temp = arr[i][lo];
arr[i][lo] = arr[hi][i];
arr[hi][i] = arr[j][hi];
arr[j][hi] = arr[lo][j];
arr[lo][j] = temp;
}
RotateClockwise90(arr, lo+1, hi-1);
}
#!/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²)时间和O(1)空间算法(没有任何变通方法和恶作剧的东西!)
旋转+90:
转置 反转每行
旋转-90:
方法一:
转置 反转每一列
方法二:
反转每行 转置
旋转180度:
方法一:旋转+90两次
方法2:反转每行,然后反转每列(转置)
旋转-180度:
方法一:旋转-90度2次
方法二:先反转每一列,再反转每一行
方法三:旋转+180,因为它们是相同的
很好的答案,但对于那些正在寻找DRY JavaScript代码的人- +90度和-90度:
// Input: 1 2 3 // 4 5 6 // 7 8 9 // Transpose: // 1 4 7 // 2 5 8 // 3 6 9 // Output: // +90 Degree: // 7 4 1 // 8 5 2 // 9 6 3 // -90 Degree: // 3 6 9 // 2 5 8 // 1 4 7 // Rotate +90 function rotate90(matrix) { matrix = transpose(matrix); matrix.map(function(array) { array.reverse(); }); return matrix; } // Rotate -90 function counterRotate90(matrix) { var result = createEmptyMatrix(matrix.length); matrix = transpose(matrix); var counter = 0; for (var i = matrix.length - 1; i >= 0; i--) { result[counter] = matrix[i]; counter++; } return result; } // Create empty matrix function createEmptyMatrix(len) { var result = new Array(); for (var i = 0; i < len; i++) { result.push([]); } return result; } // Transpose the matrix function transpose(matrix) { // make empty array var len = matrix.length; var result = createEmptyMatrix(len); for (var i = 0; i < matrix.length; i++) { for (var j = 0; j < matrix[i].length; j++) { var temp = matrix[i][j]; result[j][i] = temp; } } return result; } // Test Cases var array1 = [ [1, 2], [3, 4] ]; var array2 = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; var array3 = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ]; // +90 degress Rotation Tests var test1 = rotate90(array1); var test2 = rotate90(array2); var test3 = rotate90(array3); console.log(test1); console.log(test2); console.log(test3); // -90 degress Rotation Tests var test1 = counterRotate90(array1); var test2 = counterRotate90(array2); var test3 = counterRotate90(array3); console.log(test1); console.log(test2); console.log(test3);
PHP解决方案为顺时针和逆时针
$aMatrix = array(
array( 1, 2, 3 ),
array( 4, 5, 6 ),
array( 7, 8, 9 )
);
function CounterClockwise( $aMatrix )
{
$iCount = count( $aMatrix );
$aReturn = array();
for( $y = 0; $y < $iCount; ++$y )
{
for( $x = 0; $x < $iCount; ++$x )
{
$aReturn[ $iCount - $x - 1 ][ $y ] = $aMatrix[ $y ][ $x ];
}
}
return $aReturn;
}
function Clockwise( $aMatrix )
{
$iCount = count( $aMatrix );
$aReturn = array();
for( $y = 0; $y < $iCount; ++$y )
{
for( $x = 0; $x < $iCount; ++$x )
{
$aReturn[ $x ][ $iCount - $y - 1 ] = $aMatrix[ $y ][ $x ];
}
}
return $aReturn;
}
function printMatrix( $aMatrix )
{
$iCount = count( $aMatrix );
for( $x = 0; $x < $iCount; ++$x )
{
for( $y = 0; $y < $iCount; ++$y )
{
echo $aMatrix[ $x ][ $y ];
echo " ";
}
echo "\n";
}
}
printMatrix( $aMatrix );
echo "\n";
$aNewMatrix = CounterClockwise( $aMatrix );
printMatrix( $aNewMatrix );
echo "\n";
$aNewMatrix = Clockwise( $aMatrix );
printMatrix( $aNewMatrix );