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)
  • 相关阅读:
    Ubuntu 16.04 OneDrive自动同步
    在conda环境中pip使用清华源秒速安装skimage、opencv、tensorflow、pytorch1.2.0等p
    写论文的最佳实践
    训练误差、测试误差、泛化误差的区别
    输入法 ctrl+句号 切换 中英文符号
    理解Graham扫描算法 查找凸包
    PDF阅读器 SumatraPDF 设置:电子书字体字号的更换及行距设置
    友情链接
    CRC全套~~~ 转载
    mysql插入中文出错,提示1366
  • 原文地址:https://www.cnblogs.com/flix/p/13516193.html
Copyright © 2011-2022 走看看