LeetCode Top 100 Liked Questions 48. Rotate Image (Java版; Medium)

welcome to my blog

LeetCode Top 100 Liked Questions 48. Rotate Image (Java版; Medium)

题目描述
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]
]
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        if(n<=1){
            return;
        }
        //转置
        for(int i=0; i<n; i++){
            for(int j=i+1; j<n; j++){
                swap(matrix, i, j, j, i);
            }
        }
        //水平翻转
        for(int j=0; j<n/2; j++){
            for(int i=0; i<n; i++){
                //l-0 = n-1-r ==> r = n-1-l
                swap(matrix, i,j, i, n-1-j);
            }
        }
    }

    private void swap(int[][] arr, int i, int j, int m, int n){
        int tmp = arr[i][j];
        arr[i][j] = arr[m][n];
        arr[m][n] = tmp;
    }
}
第一次做;时间复杂度O(N^2),空间复杂度O(1); 最重要的有两点: 内外循环的起始值和终止值, 外循环的终止值和顺时针打印矩形那道题非常像; 待旋转的四个数的坐标; 画图看, 向题解那样:先研究每个元素在旋转的过程中如何移动, 发现规律后将给定的矩阵分成四个矩形并且将原问题划归为旋转这些矩形的问题

  • 注意审题, 矩阵限制为方阵, 不是任意形状的
/*
注意矩阵是n*n的!不是任意形状
有点类似顺时针打印矩阵的样子, 仅仅是类似, 别想太多
*/
class Solution {
    public void rotate(int[][] matrix) {
        if(matrix==null || matrix.length==0)
            return;
        int n = matrix.length;
        //外循环循环n/2次, 第0次从(0,0)开始, 第1次从(1,1)开始,...  也就是说,每次从对角线元素开始
        for(int i=0; i<n/2; i++){
            //n- 2*1 - 1的解释
            //每一圈的正方形边长为a的话, 每一圈过后正方形的边长减2, 也就是a-2
            //对于每一个正方形, 分解出来的矩形长度为边长减1
            for(int j=i+1; j<= n-1-i; j++){
                /*
                * 矩形的四个点(先把这四个点坐标写出来, 不容易乱):
                * 左上(i,j), 右上(j, n-1-i)
                * 左下(n-1-j, i), 右下(n-1-i, n-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;
            }
        }
    }
}
第一次做; 先对数组进行转置, 再将数组水平翻转; 要掌握数组的转置操作和水平翻转操作, 转置操作只操作上三角矩阵即可, 水平翻转操作只操作一半的元素即可, 边界是cols/2-1, 长度为偶数, cols/2-1指向中间两个数靠左的那个, 长度为奇数,cols/2-1指向中间元素的左边的元素; 时间复杂度O(N^2), 空间复杂度O(1)
class Solution {
    public void rotate(int[][] matrix) {
        if(matrix==null || matrix.length==0)
            return;
        int rows = matrix.length, cols = matrix[0].length;
        //先转置矩阵
        //只操作上三角矩阵即可
        for(int i=0; i<rows; i++){
            for(int j=i; j<cols; j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
        //再水平翻转数组
        //纵坐标满足 m-0 = cols-1-n
        for(int i=0; i<rows; i++){
            for(int j=0; j<=cols/2-1; j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[i][cols-1-j];
                matrix[i][cols-1-j] = temp;
            }
        }
    }
}
第一次做; 第一行变成第一列, 找到这个规律后直接申请的等大小的数组进行赋值, 最后再赋值回matrix; 不能直接使用matrix = arr, 必须一个一个遍历, 因为修改matrix不会影响到函数外面的matrix; 修改matrix指向的内容能影响到外面的matrix的内容; 时间复杂度O(N^2), 空间复杂度O(N^2)
/*
类似矩阵的转置
第一行变成最后一列
第二行变成倒数第二列
...
最后一行变成第一列
对于m*n的矩阵来说,索引从0开始
(i,j)换到(j, m-1-i)的位置处
*/
class Solution {
    public void rotate(int[][] matrix) {
        if(matrix==null || matrix.length==0)
            return;
        
        int rows = matrix.length, cols = matrix[0].length;
        int[][] arr = new int[rows][cols];
        for(int i=0; i<rows; i++){
            for(int j=0; j<cols; j++){
                arr[j][rows-1-i] = matrix[i][j];
            }
        }
        //matrix = arr; 不能这么写, 因为这个matrix不会影响到该函数外面的matrix; 如果修改的是matrix指向的内容, 那么这个修改是能影响到外面的
        //赋值给matrix
        for(int i=0; i<rows; i++)
            for(int j=0; j<cols; j++){
                matrix[i][j] = arr[i][j];
            }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值