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


当前回答

这个解决方案不关心正方形或矩形的尺寸,你可以旋转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("]");
    }
}

其他回答

在JavaScript中实现dimple的+90伪代码(例如转置然后反转每一行):

function rotate90(a){
  // transpose from http://www.codesuck.com/2012/02/transpose-javascript-array-in-one-line.html
  a = Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
  // row reverse
  for (i in a){
    a[i] = a[i].reverse();
  }
  return a;
}

这是我在C中的就地实现

void rotateRight(int matrix[][SIZE], int length) {

    int layer = 0;

    for (int layer = 0; layer < length / 2; ++layer) {

        int first = layer;
        int last = length - 1 - layer;

        for (int i = first; i < last; ++i) {

            int topline = matrix[first][i];
            int rightcol = matrix[i][last];
            int bottomline = matrix[last][length - layer - 1 - i];
            int leftcol = matrix[length - layer - 1 - i][first];

            matrix[first][i] = leftcol;
            matrix[i][last] = topline;
            matrix[last][length - layer - 1 - i] = rightcol;
            matrix[length - layer - 1 - i][first] = bottomline;
        }
    }
}

Javascript解决NxN矩阵与运行时O(N^2)和内存O(1)

  function rotate90(matrix){
    var length = matrix.length
    for(var row = 0; row < (length / 2); row++){
      for(var col = row; col < ( length - 1 - row); col++){
        var tmpVal = matrix[row][col];
        for(var i = 0; i < 4; i++){
          var rowSwap = col;
          var colSwap = (length - 1) - row;
          var poppedVal = matrix[rowSwap][colSwap];
          matrix[rowSwap][colSwap] = tmpVal;
          tmpVal = poppedVal;
          col = colSwap;
          row = rowSwap;
        }
      }
    }
  }

顺时针或逆时针旋转2D数组的常用方法。

顺时针旋转 首先颠倒上下,然后交换对称 1 2 3 7 8 9 7 4 4 5 6 => 4 5 6 => 8 5 7 8 9 1 2 3 9 6 3

void rotate(vector<vector<int> > &matrix) {
    reverse(matrix.begin(), matrix.end());
    for (int i = 0; i < matrix.size(); ++i) {
        for (int j = i + 1; j < matrix[i].size(); ++j)
            swap(matrix[i][j], matrix[j][i]);
    }
}

逆时针方向旋转 首先从左到右反向,然后交换对称 1 2 3 3 2 1 3 6 9 4 5 6 => 6 5 4 => 2 5 7 8 9 9 8 7 1 4 7

void anti_rotate(vector<vector<int> > &matrix) {
    for (auto vi : matrix) reverse(vi.begin(), vi.end());
    for (int i = 0; i < matrix.size(); ++i) {
        for (int j = i + 1; j < matrix[i].size(); ++j)
            swap(matrix[i][j], matrix[j][i]);
    }
}
private static int[][] rotate(int[][] matrix, int n) {
    int[][] rotated = new int[n][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            rotated[i][j] = matrix[n-j-1][i];
        }
    }
    return rotated;
}