• LeetCode第[48]题(Java):Rotate Image


    题目:矩阵旋转

    难度: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.

    翻译:你有一个n*n 的2D矩阵表示一个图像。

    将图像旋转90度(顺时针)。

    注意:

    你必须在原地旋转图像,这意味着你必须直接修改输入2D矩阵。不要分配另一个2D矩阵并进行旋转。

    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]
    ]
     

    我的思路:旋转90°,那就是把矩阵分为四块,只对第一块进行循环,然后用第一块的元素下标【i】【j】的表达式分别表示其他块的对应元素,然后把四个元素进行交换即可

    先将矩阵分为如下四块:

    A B

    C D

    现在对A内元素进行循环,其元素下标表示为【i】【j】

    1、将A的此元素用temp存储起来,

    2、A的此元素取C区域对应的元素值,C区对应元素表示为A元素“先关于矩阵主对角线取对称,然后再取纵向中心对折”

      主对角线取对称,就是【i】【j】=》【j】【i】

      纵向中心对折,就是【i】【j】=》【n-1- i 】【j】  

    3、C区此元素取D区域对应的元素值,D区对应元素表示为A元素的中心对称,即“先关于横向中心对折,然后再取纵向中心对折”

      横线中心对折,就是【i】【j】=》【i】【n-1- j】

     4、D区此元素取B区域对应的元素值,B区对应元素表示为A元素“先关于横向中心对折,然后再取矩阵副对角线对称”

      副对角线对称,就是【i】【j】=》【n-1-j】【n-1-i】

     5、B区此元素取之前A区的值,即为 temp ,到此一轮交换结束。

    需要注意的是,当矩阵的大小是偶数的时候,此时行数的对称中心 x 为对称线的上面的一个。

    例如:

    0

    1

    2

    3   此时的 x = n-1 = 1,此时是需要进行交换的行范围是【0~x】,列范围也是【0~x】

      而如果是奇数,则行范围是【0~x-1】,列范围没变还是【0~x】

    所以循环的时候需要注意判断奇偶,然后跳过。

    我的代码

     1     public void rotate(int[][] matrix) {
     2         int n = matrix.length;
     3         if (n <= 1) {
     4             return;
     5         }
     6         
     7         int even = 1;
     8         if (matrix.length % 2 == 1) {
     9             even = 0;
    10         }
    11         
    12         int x = (n-1)/2;
    13         for (int i = 0; i <= x; i++) {
    14             for (int j = 0; j <= x; j++) {
    15                 if (even==0 && i==x) {
    16                     continue;
    17                 }
    18                 int temp = matrix[i][j];
    19                 matrix[i][j] = matrix[n-1-j][i];
    20                 matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
    21                 matrix[n-1-i][n-1-j] = matrix[n-1-(n-1-j)][n-1-i];
    22                 matrix[n-1-(n-1-j)][n-1-i] = temp;
    23             }
    24         }
    25     }

    我的复杂度:O(N2

    编码过程中的问题

     1、应该使用A的元素下标【i】【j】去表示其他块所有,而不是用相对位置;

     2、对“对称”“对折”的下标变化不熟悉,导致浪费不少时间;(还想了半天用 2x - i + even 来表示,其实直接 n-1-i 即可)

     3、之前没考虑到矩阵奇偶对循环范围的影响,导致奇数的对称线没有交换;

     4、当方法定义返回为void的时候,需要直接返回,写return就行。

    答案代码

     1     public void rotate(int[][] matrix) {
     2         int n = matrix.length;
     3         if (n <= 1) {
     4             return;
     5         }
     6         
     7         int x = (n-1)/2;
     8         for (int i = 0; i <= x; i++) {
     9             int[] tmp = matrix[i];
    10             matrix[i] = matrix[n-1-i];
    11             matrix[n-1-i] = tmp;
    12         }
    13         
    14         for (int i = 0; i < n; i++) {
    15             for (int j = i+1; j < n; j++) {
    16                 int temp = matrix[i][j];
    17                 matrix[i][j] = matrix[j][i];
    18                 matrix[j][i] = temp;
    19             }
    20         }
    21     }

    答案复杂度:O(N2

    答案思路

    首先将整个数组上下对称交换

    1 2 3     7 8 9 
    4 5 6  => 4 5 6
    7 8 9     1 2 3

    然后再关于主对角线对称交换

    7 8 9     7 4 1
    4 5 6  => 8 5 2
    1 2 3     9 6 3

    优点:逻辑清晰明了

    缺点:复杂度比我的方法高一点

     

    扩展

     逆时针旋转90°?

    我的方法——ABCD块之间的取值关系会发生变化。

    答案方法——有两种修改方法都行:

          a:第一步和第二步交换,即先对角线,后对折

          b:把第一步的上下对称交换改成左右对称交换,第二步不变。

  • 相关阅读:
    闭包函数+装饰器(第十一天)
    函数初接触2
    函数初接触
    第八天
    第八天
    第七天
    day4—day6作业(补发)
    第六天
    第五天
    python基础学习-常用模块的使用(扩展补充,高级使用)(三)
  • 原文地址:https://www.cnblogs.com/Xieyang-blog/p/9015493.html
Copyright © 2020-2023  润新知