程序员面试金典:面试题 01.07. 旋转矩阵
给你一幅由 N × N
矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?
//使用了额外内存空间 class Solution { public void rotate(int[][] matrix) { int m = matrix.length; int[][] copyMatrix = new int[m][m]; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { copyMatrix[i][j] = matrix[m - 1 - j][i]; } } for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { matrix[i][j] = copyMatrix[i][j]; } } } }
进阶:不使用额外空间
观察图中颜色相同的四个位置,当旋转 90 度后,对应位置的元素发生了顺时针的交换。
而相隔的两个位置是中心对称的,基于此可以计算出发生交换的四个元素 位置关系。
设四个位置中,位于 左上角区域 的位置坐标为 (i,j),则按顺时针顺序,四个位置分别为(i,j), (j, n-i-1), (n-i-1,n-j-1), (n-j-1,i)。其中 n 为 matrix.size(), i, j 分别为matrix的行列下标,从 0 开始。
整个矩阵的旋转可以理解为 起点都在左上角区域,然后依次顺时针移动。
matrix.size() 为奇数时,位置的对应关系相同,但左上角区域并 不是整个矩阵的四分之一,如下图示:
其实就是多了中间列的上半部分。
那么现在捋一下如何 原地操作元素:枚举左上区域的所有位置,然后通过上面总结的位置关系直接交换元素。
对于一个位置 (i,j),需要 交换三次:
swap(matrix, i, j, j, n - 1 - i); swap(matrix, i, j, n - 1 - i, n - 1 - j); swap(matrix, i, j, n - 1 - j, i);
整体代码如下:
class Solution { public void rotate(int[][] matrix) { int n = matrix.length; if (n == 0) { return; } int row = n / 2 - 1;//左上角区域最下面一行 int column = (n - 1) / 2;//左上角区域最右面一列 for (int i = 0; i <= row; i++) {//数学知识,两两中心对称 for (int j = 0; j <= column; j++) { swap(matrix, i, j, j, n - 1 - i); swap(matrix, i, j, n - 1 - i, n - 1 - j); swap(matrix, i, j, n - 1 - j, i); } } } private void swap(int[][] matrix, int i, int j, int m, int n) { int temp = matrix[i][j]; matrix[i][j] = matrix[m][n]; matrix[m][n] = temp; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】