首页 简历|笔试面试

48.旋转图像

  • 25年9月4日 发布
  • 842.77KB 共10页
48.旋转图像48.旋转图像48.旋转图像48.旋转图像48.旋转图像

48. 旋转图像

二哥瞎逼逼:9 月份对于准备秋招的球友来说,非常重要,但奇怪的是 9 月份的

假期却很多,中秋过完马上就是国庆,就很容易刚提起劲然后就松懈下来,然后

一眨眼就 10 月中旬了。国庆结束后,基本上 offer 就开奖了,也就意味着头部

和肩部选手的秋招可以彻底告一个段落了。今天继续来一到 LeetCode 题,醒醒

脑子。

题意

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

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

矩阵来旋转图像。

难度

中等

示例

示例 1:

048.旋转图像-20240918153439.png

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]

输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

048.旋转图像-20240918153507.png

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]

输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

分析 1

在我们上学的年级,经常出现一些找规律的题目,比如说 1,1,2,3,5,8,13,21 这样的数列,

我们很容易找到这样一个规律,就是后一个数等于前两个数之和。

对于这道题,我们也可以找到这样一个规律:

• 第 i 行的元素旋转到了第 n-1-i 列;

• 第 j 列的元素旋转到了第 j 行。

048.旋转图像-20240918154554.png

一旦找到这个规律,题解就很容易了,我们只需要遍历一遍矩阵,然后将矩阵的元素旋转

到对应的位置即可。

为了保证旋转的过程中有些元素不会被覆盖,我们可以对矩阵进行深拷贝。

题解如下:

class Solution04801 {

public void rotate(int[][] matrix) {

int n = matrix.length; // 获取矩阵的维度

int[][] matrix_new = new int[n][n]; // 创建一个新矩阵来保存原矩阵的副本

// 复制原矩阵的每一行到新的矩阵

for (int i = 0; i < n; i++) {

matrix_new[i] = Arrays.copyOf(matrix[i], n); // 复制每一行

}

// 旋转矩阵:将 matrix_new 中的元素重新放入 matrix 中

for (int i = 0; i < n; i++) { // 遍历原矩阵的每一行

for (int j = 0; j < n; j++) { // 遍历原矩阵的每一列

// 将 matrix_new[i][j] 旋转到 matrix[j][n - 1 - i]

matrix[j][n - 1 - i] = matrix_new[i][j];

}

}

}

public static void main(String[] args) {

Solution04801 solution = new Solution04801();

int[][] matrix = {

{1, 2, 3},

{4, 5, 6},

{7, 8, 9}

};

solution.rotate(matrix);

for (int[] row : matrix) {

for (int val : row) {

System.out.print(val + " ");

}

System.out.println();

}

// 输出:

// 7 4 1

// 8 5 2

// 9 6 3

}

}

来看一下题解效率:

048.旋转图像-20240918160613.png

很高,但是因为我们多了一个 matrix_new 的二维数组,所以在严格意义上并不符合原地

旋转的要求。

分析 2

矩阵旋转 90 度,相当于把 A 挪到 B,B 挪到 C,C 挪到 D,D 挪到 A,这样的操作。

048.旋转图像-20240918161300.png

比如说一个 4x4 的矩阵,相当于是 2 层的同心圆,我们可以通过一层一层的旋转来完成

整个矩阵的旋转。

class Solution04802 {

public void rotate(int[][] matrix) {

int n = matrix.length;

// 逐层旋转

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

int first = layer; // 当前层的起始索引

int last = n - 1 - layer; // 当前层的结束索引

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

int offset = i - first; // 偏移量,用来计算位置

// 保存上边

int top = matrix[first][i];

// 左边 -> 上边

matrix[first][i] = matrix[last - offset][first];

// 下边 -> 左边

matrix[last - offset][first] = matrix[last][last - offset];

// 右边 -> 下边

matrix[last][last - offset] = matrix[i][last];

// 上边 -> 右边

matrix[i][last] = top;

}

}

}

public static void main(String[] args) {

Solution04802 solution = new Solution04802();

int[][] matrix = {

{ 1, 2, 3, 4},

{ 5, 6, 7, 8},

{ 9, 10, 11, 12},

{13, 14, 15, 16}

};

solution.rotate(matrix);

for (int[] row : matrix) {

for (int val : row) {

System.out.print(val + " ");

}

System.out.println();

}

// 输出:

// 13 9 5 1

// 14 10 6 2

// 15 11 7 3

// 16 12 8 4

}

}

题解效率也很高。

048.旋转图像-20240918162156.png

分析 3

旋转 90 度其实,就相当于先沿着对角线翻转,再沿着中轴线翻转。

048.旋转图像-20240918162855.png

也就是说:

①、对角线反转:将矩阵的行和列进行互换。即 matrix[i][j] 变为 matrix[j][i]。

②、中轴线反转:将翻转后的矩阵的每一行进行左右翻转。这样就可以得到旋转 90 度的

结果。

class Solution {

public void rotate(int[][] matrix) {

int n = matrix.length;

// 1. 对角线翻转

for (int i = 0; i < n; i++) {

for (int j = i; j < n; j++) {

int temp = matrix[i][j];

matrix[i][j] = matrix[j][i];

matrix[j][i] = temp;

}

}

// 2. 中轴线翻转

for (int i = 0; i < n; i++) {

for (int j = 0; j < n / 2; j++) {

int temp = matrix[i][j];

matrix[i][j] = matrix[i][n - 1 - j];

matrix[i][n - 1 - j] = temp;

}

}

}

}

来看一下题解效率:

048.旋转图像-20240918163629.png

总结

?道的关

题的于

住关 在

找 键在 于 找 规律 : “旋 转后 的 元 素 和 旋 转之 前 的 关 系 ”, 找 不 到 就 记住 ? :

• 第一种解法中我们用空间换时间,需要借助一个额外的数组;

• 第二种解法我们把矩阵分成了一层一层,然后逐层旋转;

• 第三种解法我们先沿着对角线翻转,再沿着中轴线翻转。

其实就在于找到元素下标反转前后的关系。

假设矩阵的大小为 n × n,元素位于原矩阵中的位置为 (i, j),那么在顺时针旋转 90 度后,

元素的新位置应该为 (j, n - 1 - i)。

力扣链接:https://leetcode.cn/problems/rotate-image/

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
一键复制 下载文档 联系客服