leetcode
leetcode 1 ~ 50
旋转图像

旋转图像

难度:

标签:

题目描述

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

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

 

示例 1:

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

示例 2:

输入: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]]

 

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

 

代码结果

运行时间: 44 ms, 内存: 14.8 MB


/* 思路: 使用Java Stream进行相同的旋转操作。虽然Stream不直接修改数据结构,但可以用于生成中间结果。 
   1. 水平翻转:将第i行与第(n-i-1)行交换。 
   2. 主对角线翻转:将matrix[i][j]与matrix[j][i]交换。 
*/ 
 
import java.util.stream.IntStream; 
 
public class RotateImageStream { 
    public void rotate(int[][] matrix) { 
        int n = matrix.length; 
        // 水平翻转 
        IntStream.range(0, n / 2).forEach(i -> { 
            IntStream.range(0, n).forEach(j -> { 
                int temp = matrix[i][j]; 
                matrix[i][j] = matrix[n - i - 1][j]; 
                matrix[n - i - 1][j] = temp; 
            }); 
        }); 
        // 主对角线翻转 
        IntStream.range(0, n).forEach(i -> { 
            IntStream.range(i + 1, n).forEach(j -> { 
                int temp = matrix[i][j]; 
                matrix[i][j] = matrix[j][i]; 
                matrix[j][i] = temp; 
            }); 
        }); 
    } 
}

解释

方法:

这个题解采用了两步操作来实现矩阵的顺时针旋转90度。第一步是将矩阵进行转置,即将矩阵的行列进行互换。第二步是将转置后的矩阵的每一行进行反转。经过这两步操作,原矩阵就被顺时针旋转了90度。这种方法可以在原地修改矩阵,不需要使用额外的矩阵空间。

时间复杂度:

O(n^2)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在顺时针旋转图像时,首先选择转置矩阵而不是其他操作?
在顺时针旋转图像时,首先选择转置矩阵是为了简化旋转操作。通过转置,原矩阵的行变成了列,这样只需要进行行的反转即可完成顺时针旋转。如果不先转置,将需要复杂的坐标映射来直接实现旋转,这不仅编程复杂,而且容易出错。转置和行反转的组合使得代码更简洁、易于理解,并且可以在原地完成,不需要额外空间。
🦆
在转置矩阵过程中,为什么只遍历矩阵的上三角区域而不是整个矩阵?
在转置矩阵的过程中,只遍历上三角区域是为了避免重复交换元素。如果遍历整个矩阵进行元素交换,每个元素会被交换两次,最终导致矩阵未发生任何改变。通过限制在上三角区域,每对元素只交换一次,确保每个元素都正确地移动到其转置位置。
🦆
在将转置后的矩阵的每一行反转时,这种操作是否会影响矩阵的其他属性,如行列的对称性?
将转置后的矩阵的每一行反转主要是为了完成90度旋转,这个操作改变了矩阵的行列对应关系,从而改变了矩阵的行列对称性。而且,该操作会导致原本对称或者非对称的矩阵失去其原有的对称特性。因此,可以说这种操作改变了矩阵的某些属性,如对称性。
🦆
旋转操作完成后,有没有可能矩阵中的某些行或列超出了原始矩阵的边界?
在这种旋转操作中,所有的操作都是在原矩阵的尺寸范围内完成的。转置操作改变了元素的行列位置但保持在原矩阵的边界内,行反转也同样只是改变了元素在行内的顺序而已。因此,不会有任何行或列超出原始矩阵的边界。这个旋转操作是完全在原矩阵的尺寸范围内进行的。

相关问题