力扣第四十八题-旋转图像

455 阅读2分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

前言

力扣第四十八题 旋转图像 如下所示:

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

image.png

示例 2:

image.png

一、思路

这一题最难的一点就是需要原地旋转图像,也就是说只能使用常数级的额外空间来实现转换。

实现思路主要分为以下两个部分:

  • 分圈转换,从外至内:如 4 x 4 的矩阵,共有两圈
  • 某一圈交换时,只关注前 n- 1 - i 个元素,且每个元素需要交换三次

图解原地旋转

matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 作为例子讲述

分圈转换,从外至内

这个 4 x 4 的矩阵只有两个圈,我们只需要处理这两个圈即可

image.png

某一圈交换时

此处以外圈 ①号圈 作为例子

我们只需要关注圈中的 5, 1, 9 即可

image.png

具体的交换逻辑如下所示(仅以第一个元素作为例子):

  1. 交换 matrix[0][0]matrix[0][3]

image.png

  1. 交换 matrix[0][0]matrix[3][3]

image.png

  1. 交换 matrix[0][0]matrix[3][0]

image.png

交换的规律

交换的规律我做了以下总结:

  1. 以圈中的前 n - 1- i 个元素作为基准
  2. 某一个点需要交换三次,三个点的特征如下:
    • 交换的第一个点:列固定
    • 交换的第二个点:行固定
    • 交换的第三个点:列固定

二、实现

实现代码

实现代码与思路中保持一致

    public void rotate(int[][] matrix) {
        int n = matrix.length;
        // nxn 的二维数组需要旋转 n-2 次(n>2)
        for (int i=0; i == 0 || i<n-2; i++) {
            int end = n- 1 - i;
            // 每一圈需要置换多少个点为 n-2*i-1
            for (int j=0; j<n-2*i-1; j++) {
                // 每个点值需要置换三次
                for (int m=0; m<3; m++) {
                    int temp = matrix[i][i+j];
                    if (m==0) { // 替换第一个数(列固定)
                        matrix[i][i+j] = matrix[i + j][end];
                        matrix[i + j][end] = temp;
                    } else if (m==1){   // 替换第二个数(行固定)
                        matrix[i][i+j] = matrix[end][end - j];
                        matrix[end][end - j] = temp;
                    } else {    // 替换第三个数(列固定)
                        matrix[i][i+j] = matrix[end - j][i];
                        matrix[end - j][i] = temp;
                    }
                }
            }
        }
    }

测试代码

public static void main(String[] args) {
    int[][] matrix = {{5,1,9,11},{2,4,8,10},{13,3,6,7},{15,14,12,16}};
    int[][] matrix1 = {{1,2},{3,4}};
    new Number48().rotate(matrix1);
}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥