• 【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)
  • 相关阅读:
    我决定重新开始搞机器学习啦
    基于问句实体扩展和全局规划的答案摘要方法研究相关论文
    cjson源代码解读(三) 解析字符串、数字、数组、对象
    论文阅读:DeepWalk
    cjson源代码解读 (二)解析流程
    cjson源代码解读 (一)介绍
    DDoS攻击的几种类型
    Nmap扫描二级目录
    一次域环境的渗透
    利用enum4linux 445端口+wordpress插件任意文件上传的一次渗透
  • 原文地址:https://www.cnblogs.com/flix/p/13516193.html
Copyright © 2020-2023  润新知