《程序员面试金典(第6版)》面试题 01.07. 旋转矩阵

题目描述

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?

示例 1:

  • 给定 matrix =
    [
    [1,2,3],
    [4,5,6],
    [7,8,9]
    ],

  • 原地旋转输入矩阵,使其变为:
    [
    [7,4,1],
    [8,5,2],
    [9,6,3]
    ]

示例 2:

  • 给定 matrix =
    [
    [ 5, 1, 9,11],
    [ 2, 4, 8,10],
    [13, 3, 6, 7],
    [15,14,12,16]
    ],

  • 原地旋转输入矩阵,使其变为:
    [
    [15,13, 2, 5],
    [14, 3, 4, 1],
    [12, 6, 8, 9],
    [16, 7,10,11]
    ]

解题思路

这道题对我来说是感觉挺难的,首先来说一下第一种解法吧,我给它起名叫做四角3次交法。为什么这么叫呢,这是因为我们会使用双层for循环去变量这个vector。首先我们将矩形的四个角按顺时针的顺序,分别命名为:
[i,j] , [j,N-1-i] , [N-i-1][N-j-1] , [N-j-1][i]
我们每遍历一次,实际上就有4个元素交换了位置。那如何实现呢?其实就是第一个角会分别与这3个角去交换元素。每遍历一个元素,就要交换三次,交换3次后,4个角上的元素就分别交换了位置了。所以我给它取名为4角3次交换法。
具体交换的代码就长这样:

				swap(matrix[i][j],matrix[j][N-i-1]);
                swap(matrix[i][j],matrix[N-i-1][N-j-1]);
                swap(matrix[i][j],matrix[N-j-1][i]);

下面我再拿图给大家演示一下,宏观上我们看到元素1换到了3的位置,3换到了9的位置,9换到了7的位置,7换到了1的位置。但实际上我们的代码交换逻辑是拿位置为(0,0)的元素分别与(0,2),(2,2)(2,0)的元素顺时针交换了一次各自的元素所达成的效果。
《程序员面试金典(第6版)》面试题 01.07. 旋转矩阵_第1张图片
这道题的第二种解法叫做两次交换法,就是先将元素整体按照对角线交换一次,紧接着按照y轴交换一次
这种方法,比第一种方法其实更简单易懂一点,代码也稍微简单些。

代码展示:

四角三次交换法

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        
        int N = matrix.size();
        if(N == 0) return ;
        for(int i = 0; i < N/2; ++i){
            for(int j = 0; j < (N+1)/2; ++j){
                swap(matrix[i][j],matrix[j][N-i-1]);
                swap(matrix[i][j],matrix[N-i-1][N-j-1]);
                swap(matrix[i][j],matrix[N-j-1][i]);
            }
        }
        return;   
    }
};

其实知道了交换原理了后,按照这样的for循环,你自然知道该如何去如何用i,j去表示剩下的3个角。关于为什么j < (N+1)/2,这是因为如果矩形的长度是基数了话,j要比i多遍历一次。所以就是(N+1)/2了。

两次交换法

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        
        int N = matrix.size();
        if(N == 0 || N ==1) return ;
        for(int i = 0; i < N; ++i){
            for(int j = 0; j < i; ++j){
                swap(matrix[i][j],matrix[j][i]);
            }
        }
        for(int i = 0; i < N; ++i){
            for(int j = 0; j < N/2; j++){
                swap(matrix[i][j],matrix[i][N-1-j]);
            }
        }
        return;
        
    }
};

说实话,这种方法比上一种方法简单太多了。我简直是泪目了。

总结

这道题我感觉就是考察图形如何变化与怎么用代码表示出来,其他感觉不到什么了。有点痛苦。

你可能感兴趣的:(#,算法题解析与个人做题技巧总结,面试,矩阵,算法)