给出一个用二维矩阵表示的图像
返回该图像顺时针旋转90度的结果
扩展:
你能使用原地算法解决这个问题么?
//做两次翻转,先沿右上-左下的对角线翻转,再沿水平中线上下翻转 class Solution { public: void rotate(vector<vector<int> > &matrix) { //对角线翻转 const int n = matrix.size(); for (int i = 0; i < n; i++) for (int j = 0; j < n - i; j++) swap(matrix[i][j], matrix[n-1-j][n-1-i]); for (int i = 0; i < n/2; i++) for (int j = 0; j < n; j++) swap(matrix[i][j],matrix[n-1-i][j]); } };
public class Solution { public void rotate(int[][] matrix) { int n = matrix.length; for(int i=0;i<n/2;i++){ for(int j=i;j<n-i-1;j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[n-1-j][i]; matrix[n-1-j][i] = matrix[n-1-i][n-1-j]; matrix[n-1-i][n-1-j] = matrix[j][n-1-i]; matrix[j][n-1-i] = temp; } } } }
//层层旋转 public class Solution { public void rotate(int[][] matrix) { int n=matrix.length; int temp=0; for(int i=0;i<n/2;i++){ for(int j=i;j<n-1-i;j++){ temp=matrix[i][j]; matrix[i][j]=matrix[n-j-1][i]; matrix[n-j-1][i]= matrix[n-i-1][n-j-1]; matrix[n-i-1][n-j-1]=matrix[j][n-i-1]; matrix[j][n-i-1]=temp; } } return; } }
public class Solution { public void rotate(int[][] matrix) { int row = matrix.length; int col = matrix[0].length; int[] arr = new int[row*col]; int k = 0; //将二维数组按顺时针旋转90度的后以从左到右从上到下的顺序访问数组元素并存入一维数组中 for(int j=0; j < col ;j++){ for(int i = row-1;i >= 0 ;i--){ arr[k++] = matrix[i][j]; } } int num = 0; //按二维数组正常的从左到右从上到下的次序将一维数组赋值给二维数组 for(int i = 0;i < row ;i++){ for(int j = 0;j < col;j++){ matrix[i][j] = arr[num++]; } } } }
/*
You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Note:
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
rotate the input matrix in-place such that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
Example 2:
Given input matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
rotate the input matrix in-place such that it becomes:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
*/
/*
思路:
先按照y轴交换,再按照主对角线交换
*/
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int rows = matrix.size();
int cols = matrix[0].size();
// 按照y轴进行交换
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols / 2; ++col) {
swap(matrix[row][col], matrix[row][cols - 1 - col]);
}
}
// 按照主对角线进行交换
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols - 1 - row; ++col) {
swap(matrix[row][col], matrix[cols - 1 - col][rows - 1 - row]);
}
}
}
};
class Solution { public: void rotate(vector<vector<int> > &matrix) { int sz=matrix.size(); for(int i=0;i<sz;i++) for(int j=0;j<sz-i;j++) swap(matrix[i][j],matrix[sz-1-j][sz-1-i]); for(int i=0;i<sz/2;i++) for(int j=0;j<sz;j++) swap(matrix[i][j],matrix[sz-1-i][j]); } };
class Solution { public: /// 西安按照主对角线翻转,再每行翻转 void rotate(vector<vector<int> > &matrix) { for(int i=0;i<matrix.size();i++) { for(int j=0;j<=i;j++) swap(matrix[i][j],matrix[j][i]); } for(int i=0;i<matrix.size();i++) reverse(matrix[i].begin(),matrix[i].end()); } };
public class Solution { public void rotate(int[][] matrix) { int row = matrix.length; int column = matrix[0].length; for (int i = 0; i < row; i++) { for (int j = i + 1; j < column; j++) { matrix[i][j] = matrix[i][j] ^ matrix[j][i] ^ (matrix[j][i] = matrix[i][j]); } } for (int i = 0; i < row; i++) { for (int j = 0; j < column / 2; j++) { matrix[i][j] = matrix[i][j] ^ matrix[i][column - j - 1] ^ (matrix[i][column - j - 1] = matrix[i][j]); } } } }
/* * 交换matrix[i][j]和matrix[j][i] * Runtime: 2 ms */ public void rotate(int[][] matrix) { int n = matrix.length; for(int i=0;i<n-1;i++){ for(int j=i+1;j<n;j++){ int temp=matrix[i][j]; matrix[i][j]=matrix[j][i]; matrix[j][i]=temp; } } /* * 左右翻转 */ 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; } } } /* * 不推荐的解法 Time:O(n^2) Space:O(n^2) Runtime: 2 ms. Your runtime beats 66.24 % * of java submissions */ public void rotate_1(int[][] matrix) { int n = matrix.length; int[][] newMatrix = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { newMatrix[j][n - 1 - i] = matrix[i][j]; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) matrix[i][j] = newMatrix[i][j]; } }
public class Solution { public void rotate(int[][] matrix) { int n = matrix.length; for (int i = 0; i < n; i ++) { for (int j = 0; j < n - i; j ++) { matrix[i][j] = matrix[n - 1 - j][n - 1 - i] ^ matrix[i][j] ^ (matrix[n - 1 - j][n - 1 - i] = matrix[i][j]); } } for (int i = 0; i < n / 2; i ++) { for (int j = 0; j < n; j ++) { matrix[i][j] = matrix[n - 1 - i][j] ^ matrix[i][j] ^ (matrix[n - 1 - i][j] = matrix[i][j]); } } } }
#include<algorithm> using namespace std; class Solution { public: void rotate(vector<vector<int> > &matrix) { //do this in-place int row = matrix.size(); int col = matrix[0].size(); //对矩阵进行转置 for(int i=0;i<row;i++){ for(int j=i+1;j<col;j++){ //交换 matrix[i][j] = matrix[i][j]^matrix[j][i]; matrix[j][i] = matrix[i][j]^matrix[j][i]; matrix[i][j] = matrix[i][j]^matrix[j][i]; } } //得到的矩阵与原矩阵顺时针旋转90度的矩阵成镜像对称 for(int i=0;i<row;i++){ //reverse(matrix[i].begin(),matrix[i].end()); //自己实现翻转 int half = col>>1; for(int j=0;j<half;j++){ matrix[i][j] = matrix[i][j]^matrix[i][col-1-j]; matrix[i][col-1-j] = matrix[i][j]^matrix[i][col-1-j]; matrix[i][j] = matrix[i][j]^matrix[i][col-1-j]; } } } };
//注意调节好参数,不然就错一个数字也要调试好久 //因为旋转矩阵的时候如果仅交换两个值会有覆盖现象 //所以从容易理解的逻辑出发,需要额外存储空间暂存值,运行时间57ms空间11372k public void rotate(int[][] matrix) { int[] arr = new int[matrix.length]; //存矩形的上边(上面行) int[] arr1 = new int[matrix.length]; //存矩形的右边 if (matrix.length == 1) { return; } // 看作多个嵌套旋转的四边框,左上角坐标(i,i) for (int i = 0; i <= (matrix.length - 1) / 2; i++) { if((i==(matrix.length - 1) / 2)&&(matrix.length%2>0)){ break; } // 储存上面行 int count = 0; int nailIndex = matrix.length - 1 - i; for (int up = i; up <= nailIndex; up++) { arr[count] = matrix[i][up]; count++; } // 储存右边行 int count1 = 0; for (int rightIn = i; rightIn <= nailIndex; rightIn++) { arr1[count1] = matrix[rightIn][nailIndex]; count1++; } // 左行盖上面行 int leftTemp=i; for (int left = nailIndex; left >= i; left--) { matrix[i][left] = matrix[leftTemp][i]; leftTemp++; } // 下面换到左边 for (int down = i; down <= nailIndex; down++) { matrix[down][i] = matrix[nailIndex][down]; } // 储存的上边行覆盖右边行 count = 0; for (int rightSav = i ; rightSav <= nailIndex; rightSav++) { matrix[rightSav][nailIndex] = arr[count]; count++; } // 存储的右边换到下面 count1 = 0; for (int right = nailIndex; right >=i; right--) { matrix[nailIndex][right]=arr1[count1]; count1++; } } }
这一问题可以有如下问法(都是空间复杂度为常数级别):
对于本题,有两种思路:
思路一:利用对称进行旋转——先根据主对角线互换元素,再根据垂直中线互换元素
思路二:利用坐标映射
强烈建议用第一种方法,因为找第二种方法的坐标关系特别特别特别麻烦
举一反三:面对旋转、填充一类的题型,一定要考虑对称这一“大杀器”,它能极大的减少工作量,提高解题正确率和解题效率
思路一的代码
// // Created by jt on 2020/9/5. // #include <vector> #include <algorithm> using namespace std; class Solution { public: void rotate(vector<vector<int> > &matrix) { int n = matrix.size(); // 按主对角线反转 for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { swap(matrix[i][j], matrix[j][i]); } } // 左右反转 for (int i = 0; i < n; ++i) { for (int j = 0; j < n / 2; ++j) { swap(matrix[i][j], matrix[i][n-1-j]); } } } };
思路二的代码
// // Created by jt on 2020/9/5. // #include <vector> #include <algorithm> using namespace std; class Solution { public: void rotate(vector<vector<int> > &matrix) { int n = matrix.size(); for (int i = 0; i < n / 2; ++i) { int m = n - 2 * i; for (int j = i; j < i + m - 1; ++j) { int tmp = matrix[i][j]; matrix[i][j] = matrix[2*i-j+m-1][i]; matrix[2*i-j+m-1][i] = matrix[i+m-1][2*i-j+m-1]; matrix[i+m-1][2*i-j+m-1] = matrix[j][i+m-1]; matrix[j][i+m-1] = tmp; } } } };