最小空间复杂度 矩阵旋转

         一,问题描述 

        今天碰到一个简单的面试题,矩阵旋转。给定一个n*n的矩阵,要求逆时针旋转90度,要求两个角要同时旋转。只能使用O(1)的辅助空间。 例如,一个4*4的矩阵,旋转前后图1所示。

     

          图1 4*4的矩阵,旋转前后对比图。

          二,解决思路

          这个问题,关键就是坐标之间的转换关系,其实弄明白这个就很简单了。

          1, 确定关系

          为了想明白坐标的转换关系,先来看一个特例,看看四个角上的数字都转到哪了。

                        

          对应的四个坐标及转换关系为:

             

         用语言唐僧般的描述一下: 第一行的第一列,换到最后一行的第一列; 最后一行的第一列,换到最后一行的最后一列;....类似

         再来看看另外一个例子,旋转第一行第二列有关的数:

               

         根据这两个例子,确定下旋转的坐标规律,其实也是符合认知的(抽象思维好,可以直接想到)

            a[0][1] <--> a[n-1-1][0], a[n-2][0] <--> a[n-1-0][n-2] ,a[n-1][n-1-1] <--> a[1][n-1], a[1][n-1-0]<-->a[0][1]

         前一个数的行,是后一个数的列。 第一个数的列和第二个数的行是n-1的关系。注意最后一个 n-1-(n-1-j) = j

            

         当然,这些数之间的距离不一定是这样,也有可能是刚好相邻的四个数。

           2,确定范围

            确定了关系之后,就要确定i和j的范围,根据这四个坐标的范围就可以确定i和j的范围了。

            比如根据a[i][j]和a[n-1-i] [n-1-j] ,  0=<i  < n-1-i ; 0=<j <=n-j -1;  其实就是旋转左上角。 

            当然你也可以选另外两个来确定范围,旋转右上角啊,等等。

            三,代码

public class RotateMatrix {

  public static void rotateMatrix(int[][] matrix) {
    int n = matrix.length;

    int i = 0, j = 0;
    for (i = 0; i < n-1-i; i++) {
        for (j = 0; j <= n-1-j; j++) {
                //请参考上图理解
                System.out.println(i + " " + j);
                int tmp = matrix[n-1-j][i];
                matrix[n-1-j][i] = matrix[i][j];
                matrix[i][j] = matrix[j][n-1-i];

                matrix[j][n-1-i] = matrix[n-1-i][n-1-j];
                matrix[n-1-i][n-1-j] = tmp;
        }
    }
  }

  public static void display(int[][] a) {
        for (int i = 0; i < a.length; i++) {
             for (int j = 0; j < a.length; j++) 
                System.out.print(a[i][j] + "\t");
             System.out.println();
        }
  }

  public static int[][] generateMatrix(int n) {
        int c = 1;
        int[][] a = new int[n][n];
        for (int i = 0; i < n; i++) 
           for (int j = 0; j < n; j++) 
              a[i][j] = c++;
        return a;
  }

  public static void main(String[] args) {
 
     int[][] matrix = generateMatrix(6);
     display(matrix);
     System.out.println("After rotation: ");
     rotateMatrix(matrix);
     display(matrix);
  }
}

            四,跑的一些例子

            n = 7 


           

            五,扩展

            对于任意的n*m的矩阵,如果要逆时针旋转,转换的思路也是类似。只要把上述的坐标关系坐标范围中的n适当地换成m就行了。这个应该好理解吧。

              

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值