zoukankan      html  css  js  c++  java
  • 【LeetCode-数组】旋转矩阵(顺时针/逆时针)

    题目描述

    给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

    不占用额外内存空间能否做到?
    示例:

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

    题目链接: https://leetcode-cn.com/problems/rotate-matrix-lcci/

    思路1

    原地旋转。将矩阵顺时针旋转 90 度可以分解为两个步骤:

    • 将矩阵按照主对角线(左上~右下)反转;
    • 将矩阵的每一行按照中点进行翻转;

    代码如下:

    class Solution {
    public:
        void rotate(vector<vector<int>>& matrix) {
            if(matrix.empty()) return;
    
            int n = matrix.size();
            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-j-1]);
                }
            }
        }
    };
    
    • 时间复杂度:O(n^2)
    • 空间复杂度:O(1)

    思路2

    使用额外空间。我们对比旋转前后的两个矩阵发现:旋转前的第 1 行变成了旋转后的倒数第 1 列、旋转前的第 2 行变成了旋转后的倒数第 2 列,也就是旋转前的第 i 行变成了旋转后的倒数第 n-i-1 列,i∈[0, n-1]。代码如下:

    class Solution {
    public:
        void rotate(vector<vector<int>>& matrix) {
            if(matrix.empty()) return;
    
            int n = matrix.size();
            vector<vector<int>> copy(n, vector<int>(n, 0));
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    copy[j][n-i-1] = matrix[i][j];
                }
            }
            matrix = copy;
        }
    };
    
    • 时间复杂度:O(n^2)
    • 空间复杂度:O(1)

    拓展

    上面的代码解决的是矩阵顺时针旋转 90 度,如果是逆时针旋转 90 度,则也可以分为两个步骤:

    • 将矩阵按照次对角线(左下~右上)反转;
    • 将矩阵的每行按照中点反转;

    假设矩阵次对角线上面区域的一个元素位置为 (i, j),假设 (i, j) 以次对角线对称的位置为 (a, b),因为 i+a=n-1,j+b=n-1,所以 (i, j) 根据次对角线对称的位置为 (n-i-1, n-j-1)。代码如下:

    class Solution {
    public:
        void rotate(vector<vector<int>>& matrix) {
            if(matrix.empty()) return;
    
            int n = matrix.size();
            for(int i=0; i<n; i++){  // 次对角线翻转
                for(int j=0; j<n-i; j++){
                    swap(matrix[i][j], matrix[n-j-1][n-i-1]);
                }
            }
            
            for(int i=0; i<n; i++){  // 每行按照中点翻转
                for(int j=0; j<n/2; j++){
                    swap(matrix[i][j], matrix[i][n-j-1]);
                }
            }
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)
  • 相关阅读:
    yzoj P2344 斯卡布罗集市 题解
    yzoj P2350 逃离洞穴 题解
    yzoj P2349 取数 题解
    JXOI 2017 颜色 题解
    NOIP 2009 最优贸易 题解
    CH 4302 Interval GCD 题解
    CH4301 Can you answer on these queries III 题解
    Luogu2533[AHOI2012]信号塔
    Luogu3320[SDOI2015]寻宝游戏
    Luogu3187[HNOI2007]最小矩形覆盖
  • 原文地址:https://www.cnblogs.com/flix/p/13516193.html
Copyright © 2011-2022 走看看