受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呢?


当前回答

    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++;
            }
        }
    }

其他回答

这是一个如今被高估的面试问题。

我的建议是:不要让面试官用他们关于解决这个问题的疯狂建议把你弄糊涂了。使用白板绘制输入数组的索引,然后绘制输出数组的索引。旋转前后的列分度示例如下:

30 --> 00
20 --> 01
10 --> 02
00 --> 03

31 --> 10
21 --> 11
11 --> 12
01 --> 13

注意旋转后的数字模式。

下面提供了一个简洁的Java解决方案。经过测试,它是有效的:

 Input:
    M A C P 
    B N L D 
    Y E T S 
    I W R Z 

    Output:
    I Y B M 
    W E N A 
    R T L C 
    Z S D P 

/**
 * (c) @author "G A N MOHIM"
 * Oct 3, 2015
 * RotateArrayNintyDegree.java
 */
package rotatearray;

public class RotateArrayNintyDegree {

    public char[][] rotateArrayNinetyDegree(char[][] input) {
        int k; // k is used to generate index for output array

        char[][] output = new char[input.length] [input[0].length];

        for (int i = 0; i < input.length; i++) {
            k = 0;
            for (int j = input.length-1; j >= 0; j--) {
                output[i][k] = input[j][i]; // note how i is used as column index, and j as row
                k++;
            }
        }

        return output;
    }

    public void printArray(char[][] charArray) {
        for (int i = 0; i < charArray.length; i++) {
            for (int j = 0; j < charArray[0].length; j++) {
                System.out.print(charArray[i][j] + " ");
            }
            System.out.println();
        }


    }

    public static void main(String[] args) {
        char[][] input = 
                { {'M', 'A', 'C', 'P'},
                  {'B', 'N', 'L', 'D'},
                  {'Y', 'E', 'T', 'S'},
                  {'I', 'W', 'R', 'Z'}
                };

        char[][] output = new char[input.length] [input[0].length];

        RotateArrayNintyDegree rotationObj = new RotateArrayNintyDegree();
        rotationObj.printArray(input);

        System.out.println("\n");
        output = rotationObj.rotateArrayNinetyDegree(input);
        rotationObj.printArray(output);

    }

}

下面是PHP的递归方法:

$m = array();
            $m[0] = array('a', 'b', 'c');
            $m[1] = array('d', 'e', 'f');
            $m[2] = array('g', 'h', 'i');
            $newMatrix = array();

            function rotateMatrix($m, $i = 0, &$newMatrix)
            {
                foreach ($m as $chunk) {
                    $newChunk[] = $chunk[$i];
                }
                $newMatrix[] = array_reverse($newChunk);
                $i++;

                if ($i < count($m)) {
                    rotateMatrix($m, $i, $newMatrix);
                }
            }

            rotateMatrix($m, 0, $newMatrix);
            echo '<pre>';
            var_dump($newMatrix);
            echo '<pre>';

很好的答案,但对于那些正在寻找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);

我的旋转版本:

void rotate_matrix(int *matrix, int size)
{

int result[size*size];

    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size; ++j)
            result[(size - 1 - i) + j*size] = matrix[i*size+j];

    for (int i = 0; i < size*size; ++i)
        matrix[i] = result[i];
}

在其中,我们将最后一列改为第一行,以此类推。这可能不是最理想的,但对于理解来说是清楚的。

这是Java中的一个更好的版本:我已经为一个具有不同宽度和高度的矩阵制作了它

H是旋转后矩阵的高度 W是旋转后矩阵的宽度

 

public int[][] rotateMatrixRight(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[w - j - 1][i];
        }
    }
    return ret;
}


public int[][] rotateMatrixLeft(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;   
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[j][h - i - 1];
        }
    }
    return ret;
}

此代码基于Nick Berardi的帖子。