LeetCode - 48. 旋转图像

50 阅读1分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

本题采用递归的思想 对于每圈,我们可以将它分为四个部分:
0.png

若按上图x,y轴建立二维坐标系, 设正方形边长为n,则有如下对应关系

  • 1 与 2 中元素对应关系为 (x, y) -> (n-1-y, x)
  • 1 与 3 中元素对应关系为 (x, y) -> (n-1-x, n-1-y)
  • 1 与 4 中元素对应关系为 (x, y) -> (y, n-1-x)

那么我们该如何使用这一系列的对应关系呢?

我们可以建立一个从 [0, n-1] 的循环,对于每一次枚举 1 中的元素,我们可以将其先于 2 中的对应位置交换元素的值,
1.png

那么对应 2 中的元素就成功的更新为旋转后所对应的值,此时只需继续将 (0, 0) 处更新后的值按照对应关系依次与 3、4 中的对应元素交换值,即可得到 i = 0 时枚举旋转后的二维数组:
2.png 3.png

此后仅需进行递归操作即可。

    public void rotate(int[][] matrix) {
        dfs(0, matrix.length-1, matrix);
    }

    private static void dfs(int y, int times ,int[][] matrix) {
        if (times < 1) {
            return;
        }
        int length = matrix.length-1;
        for (int x = y; x < y+times; ++ x) {
            int j = 0;
            while (j != 4) {
                switch (j) {
                    case 1:
                        swap(x, y, length-y, x, matrix);
                        break;
                    case 2:
                        swap(x, y, length-x, length-y, matrix);
                        break;
                    case 3:
                        swap(x, y, y, length-x, matrix);
                        break;
                }
                ++ j;
            }
        }
        dfs(y+1, times-2, matrix);
    }

    private static void swap(int x1, int y1, int x2, int y2, int[][] map) {
        if (x1 == x2 && y1 == y2) return;
        map[y1][x1] ^= map[y2][x2];
        map[y2][x2] ^= map[y1][x1];
        map[y1][x1] ^= map[y2][x2];
    }

4.png

此算法时间复杂度 O(N) 空间复杂度 O(1)