有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。
给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵。
数据范围:,矩阵中的值满足
要求:空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度
public int[][] rotateMatrix (int[][] mat, int n) { // write code here for(int i=0;i<mat.length;i++){ for(int j=0;j<i;j++){ int temp=mat[i][j]; mat[i][j]=mat[j][i]; mat[j][i]=temp; } } for(int i=0;i<mat.length;i++){ for(int j=0;j<n/2;j++){ int temp=mat[i][j]; mat[i][j]=mat[i][n-1-j]; mat[i][n-1-j]=temp; } } return mat; }
public int[][] rotateMatrix (int[][] mat, int n) { // write code here int[][] res = new int[n][n]; int index = n; for(int i = 0; i < mat.length; i++) { int[] ch = mat[i]; res[i] = new int[n]; for(int j = 0; j < ch.length; j++) { res[i][j] = mat[index-1][i]; index --; } index = n; } return res; }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here // 转置 for ( int i = 0; i < n; i++ ) { for ( int j = i+1; j < n; j++ ) { swap(mat, i, j); } } // 反转每一行 for ( int[] row : mat ) { reverse(row); } return mat; } void swap(int[][] nums, int i, int j) { nums[i][j] ^= nums[j][i]; nums[j][i] ^= nums[i][j]; nums[i][j] ^= nums[j][i]; } void reverse(int[] nums) { int i = 0, j = nums.length-1; while ( i < j ) { nums[i] ^= nums[j]; nums[j] ^= nums[i]; nums[i] ^= nums[j]; i++; j--; } } }
public int[][] rotateMatrix (int[][] mat, int n) { // 互为转置的两个矩阵 //遍历矩阵的下三角矩阵,和上三角矩阵位置互换 //遍历矩阵每一行,把每一行视为一个数组,进行reverse() for(int i=0;i<mat.length;i++){ for(int j=0;j<i;j++){ //交换上三角和下三角元素 int tmp=mat[i][j]; mat[i][j]=mat[j][i]; mat[j][i]=tmp; } } for(int i=0;i<n;i++){//对每一行进行翻转 reverse(mat[i]); } return mat; } public void reverse(int[] nums){ for(int i=0;i<nums.length/2;i++){ int tmp=nums[i]; nums[i]=nums[nums.length-1-i]; nums[nums.length-1-i]=tmp; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here //常见栈,用来保存数组的每行元素 Stack<ArrayList<Integer>>stack=new Stack<>(); //每行元素入栈 for(int i=0;i<n;i++){ ArrayList<Integer> list=new ArrayList<>(); for(int j=0;j<n;j++){ list.add(mat[i][j]); } stack.push(list); } //按列遍历,从栈中取出来的这行元素就是第一列要放置的元素 for(int i=0;i<n;i++){ //取元素 ArrayList<Integer> list=stack.pop(); //遍历填充这一列 for(int j=0;j<n;j++){ mat[j][i]=list.get(j); } } return mat; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here //每行从上到下倒转 //再转置 a[i][j]=a[j][i] int h=0; int k=n-1; while(h<k){ //每行从上到下倒转 for(int a=0;a<n;a++){ //交换 int temp=mat[h][a]; mat[h][a]=mat[k][a]; mat[k][a]=temp; } h++; k--; } //转置 for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(j>=i){ int temp=mat[i][j]; mat[i][j]=mat[j][i]; mat[j][i]=temp; } } } return mat; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here int[][] res=new int[n][n]; for(int j=0;j<=n-1;j++){ ArrayList<Integer> path=new ArrayList<Integer>(); for(int i=n-1;i>=0;i--){ path.add(mat[i][j]); } int[] arr=to_arr(path); res[j]=arr; } return res; } public int[] to_arr(ArrayList<Integer> path){ int len=path.size(); int[] arr=new int[len]; for(int i=0;i<=len-1;i++){ arr[i]=path.get(i); } return arr; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here int[][] res = new int[n][n]; for (int i = 0; i < n; i ++) { for (int j = 0; j < n; j ++) { res[i][j] = mat[n - j - 1][i]; } } return res; } }
import java.util.*; public class Solution { //[[1,2,3],[4,5,6],[7,8,9]] public int[][] rotateMatrix(int[][] mat, int n) { //初步反转:[[1,4,7],[2,5,8],[3,6,9]] for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { int temp = mat[i][j]; mat[i][j] = mat[j][i]; mat[j][i] = temp; } } //二次反转:[[7,4,1],[8,5,2],[9,6,3]] for (int i = 0; i < n; i++) { for (int l = 0, r = n - 1; l < r; l++, r--) { int temp = mat[i][l]; mat[i][l] = mat[i][r]; mat[i][r] = temp; } } return mat; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // 对角线交换 for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { int tmp = mat[i][j]; mat[i][j] = mat[j][i]; mat[j][i] = tmp; } } // 水平对称交换 for (int i = 0; i < n; i++) { for (int j = 0; j < n/2; j++) { int tmp = mat[i][j]; mat[i][j] = mat[i][n-j-1]; mat[i][n-j-1] = tmp; } } return mat; } }
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here //创建一个新的n*n的矩阵 int[][] newMat = new int[n][n]; //第一行给最右一列 //第二行给右边第二列 for(int i = 0; i < n ;i++){ for(int j = 0;j < n;j++){ newMat[j][n-i-1] = mat[i][j]; } } return newMat; } }
//定义左上角点和右下角点(这道题因为是正方形,所以就只用了x,y和x是相等的) //对于每对顶点,旋转他们围成的边,再聚集顶点,直到相等 //在旋转边的时候,要进行分组,再旋转,具体来讲,就是4个一组,一组一组的旋转 public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { // write code here int x1=0; int x2=mat.length-1; while (x1<x2) rotate(mat,x1++,x2--); return mat; } public void rotate(int[][] mat,int x1,int x2){ //计算一共需要多少个分组,并且对每个分组进行旋转 int groupCount=x2-x1; for (int i=0;i<groupCount;i++) rotateByGroup(mat,x1,x2,i); } public void rotateByGroup(int[][] mat,int x1,int x2,int i){ //确定一个分组中的四个点,并且旋转 int tmp1=mat[x1][x1+i]; int tmp2=mat[x1+i][x2]; int tmp3=mat[x2][x2-i]; int tmp4=mat[x2-i][x1]; mat[x1+i][x2]=tmp1; mat[x2][x2-i]=tmp2; mat[x2-i][x1]=tmp3; mat[x1][x1+i]=tmp4; } }
【思路与代码】
对于空间复杂度 O(n^2)的要求,通过看旋转之后的坐标变化就可以知道其中的规律,即:
D[a,b] = D[n-1-b,a]
所以,如果空间复杂度没有严格要求,完全可以新建一个矩阵,然后把旋转之后的元素位置一一放到新矩阵中即可
具体代码如下:
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { //D[a,b] = D[n-b,a] //空间复杂度O(n2)的解法,就是新建一个同样大小的矩阵(数组) int[][] res = new int[n][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ res[i][j] = mat[n-1-j][i]; } } return res; } }
对于空间复杂度有要求的情况,需要在原数组上做更改,这就不像上面所说的只看一步的变化了,需要找出整个变化的循环规律
有兴趣的可以自己下去针对二阶、三阶、四阶矩阵找规律,现在直接给出变化规律:
另外,在做变换的时候,保证矩阵的左上角部分(第二象限)元素只按照上述规律变换一次即可
所以,在遍历元素的时候需要对其遍历路径进行控制
具体代码如下:
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { //D[a,b] = D[n-b,a] //空间复杂度O(1)的解法,就是在原数组上做更改 for(int i = 0;i < (n+1)/2;i++){ for(int j = 0;j < n/2;j++){ int temp = mat[i][j]; mat[i][j] = mat[n-1-j][i]; mat[n-1-j][i] = mat[n-1-i][n-1-j]; mat[n-1-i][n-1-j] = mat[j][n-1-i]; mat[j][n-1-i] = temp; } } return mat; } }
对于矩阵的逆时针旋转,也是用同样的方法去找规律,即可解题
最后,还有一种不容易想到的方法, 但是有奇效
对于矩阵的顺时针旋转,相当于将矩阵先按主对角线翻转,再左右翻转
同样的,如果是逆时针旋转,相当于将矩阵先按副对角线翻转,再左右翻转
具体代码如下:
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] mat, int n) { //先按主对角线翻转,再左右翻转 for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { int tmp = mat[i][j]; mat[i][j] = mat[j][i]; mat[j][i] = tmp; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n/2; j++) { int tmp = mat[i][(n-1) - j]; mat[i][(n-1) - j] = mat[i][j]; mat[i][j] = tmp; } } return mat; } }
更多知识点可以参考博客:happysun.top。
实时更新Java、框架、数据库、数据结构与算法,希望大家一起共同进步!
import java.util.*; public class Solution { public int[][] rotateMatrix(int[][] matrix, int n) { if(n==0||n==1) return matrix; for(int i=0;i<n/2;i++){//i<m/2 for(int j=0;j<(n+1)/2;j++){//j< (n+1)/2 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; } } return matrix; } }