• Home
  • About
    • Sybil photo

      Sybil

      Sybil's blog.

    • Learn More
    • Email
    • Github
    • Weibo
  • Posts
    • All Posts
    • All Tags
  • Projects

面试题 01.07. 旋转矩阵,递归,不使用额外空间

07 Apr 2020

预计阅读时间 ~5 分钟

leetcode中等

解题思路

1、对于每个格子 (i, j),它旋转 4 次 90°以后回到原来的位置。所以可以把(i, j)旋转4次,依次更新4个位置的旋转数据。

1, x, x      x, x, 1      x, x, x      x, x, x     1, x, 1
x, x, x  ->  x, x, x  ->  x, x, x  ->  x, x, x  -> x, x, x
x, x, x      x, x, x      x, x, 1      1, x, x     1, x, 1

2、那么对于第一列,也可以把它旋转 4 次 90°,更新完矩阵最外圈的数据。 这样就留下了内层的 大小的矩阵待处理。

1, 2, x      x, x, 1      x, x, x      x, x, x     1, 2, 1
x, x, x  ->  x, x, 2  ->  x, x, x  ->  2, x, x  -> 2, x, 2
x, x, x      x, x, x      x, 2, 1      1, x, x     1, 2, 1

3、显然,步骤2 留下的内层矩阵可以接着按照 步骤2 的方法递归处理。 ( 的矩阵比较特殊,不用旋转,但不影响结果。)

例子

拿以下这个 的 矩阵旋转举例

5, 1, 9, 11
2, 4, 8, 10
13, 3, 6, 7
15, 14, 12, 16

1) 先把一个 的矩阵的外层旋转,内层留下以下 的矩阵还是原来的样子。

rotate inner matrix: size=4, start=(0,0) end=(4,4)
5, 1, 9, 11
2, 4, 8, 10
13, 3, 6, 7
15, 14, 12, 16

外圈旋转完成
15, 13, 2, 5
14, x, x, 1
12, x, x, 9
16, 7, 10, 11

待旋转的矩阵
x, x, x, x
x, 4, 8, x
x, 3, 6, x
x, x, x, x

2、 递归的旋转内层 的矩阵

rotate inner matrix: size=2, start=(1,1) end=(3,3)
x, x, x, x
x, 4, 8, x
x, 3, 6, x
x, x, x, x

外圈旋转完成
x, x, x, x
x, 3, 4, x
x, 6, 8, x
x, x, x, x
---------

代码

class Solution {
   public void rotate(int[][] matrix) {
        int N = matrix.length;
        for (int k = 0; k < N; k += 2) {
            int M = N - k;
            int i = k/2;
            // System.out.println("rotate inner matrix: size=" + M + ", start=(" + i + "," + i + ") end=(" + (i+M) + "," + (i+M) + ")");
            // 旋转 matrix 的最外层
            // 相当于旋转第一行
            for (int j = 0; j < M - 1; ++j) {
                rotateCycle(matrix, i, j+i, N);
            }
        }
    }

    /**
     * 把 i,j 按照90度转一圈
     *
     * @param matrix
     * @param i
     * @param j
     */
    private void rotateCycle(int[][] matrix, int i, int j, int N) {
        int nextI = j;
        int nextJ = N-1-i;
        int tmp = matrix[i][j];
        while (nextI != i || nextJ != j) {
            int nextTmp = matrix[nextI][nextJ];
            matrix[nextI][nextJ] = tmp;
            tmp = nextTmp;
            int tmpI = nextI;
            nextI = nextJ;
            nextJ = N-1-tmpI;
        }
        matrix[i][j] = tmp;
    }
}


leetcode中等 Share Tweet +1