• 数组和矩阵问题:将正方形矩阵顺时针转动90度


    题目

      给定一个 N*N 的矩阵 matrix, 把这个矩阵调整成顺时针转动90度后形式。

      例如:

      1    2    3    4

      5    6    7    8

      9    10  11  12

      13  14  15  16

      顺时针转动90度后为:

      13  9    5    1

      14  10  6    2

      15  11  7    3 

      16  12  8    4

    要求

      额外空间复杂度为 O(1)

    难度

      一星

    解答

      这里仍然使用分圈处理的方式,在矩阵中用左上角的坐标(tR, tC)和右下角的坐标(dR, dC) 就可以表示一个子矩阵。比如,题目中的矩阵,当(tR, tC)=(0,0), (dR,dC)=(3,3) 时,表示的子矩阵就是整个矩阵,那么这个子矩阵最外层的部分如下:

      1   2   3  4

      5            8

      9                 12

      13     14     15    16

      在这个外圈中, 1,4,16,13 为一组,然后让1占据4的位置,4占据16的位置,16占据13的位置,13占据1的位置,一组就调整完了。然后,2,8,15,9 为一组,继续占据调整的过程,最后 3,12,14,5 为一组,继续占据调整的过程。然后(tR, tC)=(0,0)、(dR,dC)=(3,3) 的子矩阵外层就调整完毕了。接下来令tR和tC加1,dR和dC减1,即(tR,tC)=(1,1), (dR, dC)=(2,2), 此时表示的子矩阵如下:

      6    7

      10  11

      这个外层只有一组,就是6,7,11,10,占据调整之后即可。所以,如果子矩阵的大小是M*M,一共就有 M-1 组, 分别进行占据调整即可。

      具体过程请参看如下代码的 rotate 方法。

     1 public class Main {
     2     
     3     public static void main(String[] args) {
     4         int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
     5         System.out.println("原矩阵:");
     6         for(int i = 0; i < matrix.length; i++){
     7             for(int j = 0; j < matrix[i].length; j++){
     8                 System.out.print(matrix[i][j] + " ");
     9             }
    10             System.out.println();
    11         }
    12         
    13         new Main().rotate(matrix);
    14         System.out.println("
    顺时针旋转90度后:");
    15         for(int i = 0; i < matrix.length; i++){
    16             for(int j = 0; j < matrix[i].length; j++){
    17                 System.out.print(matrix[i][j] + " ");
    18             }
    19             System.out.println();
    20         }
    21     }
    22     
    23     //顺时针旋转90度
    24     public void rotate(int[][] matrix){
    25         int tR = 0;
    26         int tC = 0;
    27         int dR = matrix.length - 1;
    28         int dC = matrix[0].length - 1;
    29         while(tR <= dR && tC <= dC){
    30             rotateEdge(matrix, tR++, tC++, dR--, dC--);
    31         }
    32     }
    33     
    34     //旋转子矩阵外层
    35     public void rotateEdge(int[][] m, int tR, int tC, int dR, int dC){
    36         //确定旋转次数
    37         int times = dR - tR;
    38         for(int i = 0; i < times; i++){
    39             //要交换的四个位置按顺时针方向分别为:m[tR][tC+i]、m[tR+i][dC]、m[dR][dC-i]、m[dR-i][tC]
    40             int tmp = m[tR][tC+i];
    41             m[tR][tC+i] = m[dR-i][tC];
    42             m[dR-i][tC] = m[dR][dC-i];
    43             m[dR][dC-i] = m[tR+i][dC];
    44             m[tR+i][dC] = tmp;
    45         }
    46     }
    47     
    48 }
  • 相关阅读:
    错误
    分页查询
    异步请求jquery
    深入理解C/C++ [Deep C (and C++)]
    C语言经典算法100例(三)
    《Python》 计算机基础
    Python程序员的进化史
    以前没有写笔记的习惯,现在慢慢的发现及时总结是多么的重要。 这一篇文章主要关于java多线程一些常见的疑惑点。因为讲解多线程的书籍和文章已经很多了,所以我也不好意思多说,嘻嘻嘻、大家可以去参考一些那些书籍。我这个文章主要关于实际的一些问题。同时也算是我以后复习的资料吧,。还请大家多多指教。 同时希望多结交一些技术上的朋友。谢谢。
    快速读入函数
    一元二次方程公式
  • 原文地址:https://www.cnblogs.com/zlxyt/p/10514666.html
Copyright © 2020-2023  润新知