24、【数组】旋转矩阵(C++版)

题目描述

在这里插入图片描述
在这里插入图片描述

题目分析

目标矩阵的行列数相同,均为n。此题是n×n型矩阵的旋转,重点把握好旋转前后行、列索引编号的变化。通过对旋转前后的索引编号进行分析,从而找出旋转后的变化关系即可。

解法一:辅助数组

当旋转第一行时,
(0,0) => (0,3)
(0,1) => (1,3)
(0,2) => (2,3)
(0,3) => (3,3)
在这里插入图片描述

当旋转第二行时,
(1,0) => (0,2)
(1,1) => (1,2)
(1,2) => (2,2)
(1,3) => (3,2)
在这里插入图片描述

设行索引编号为x,列索引编号为y,通过观察可发现,经过旋转后的列索引变为n - x - 1,行索引变为y。

因此可根据上述关系可知,旋转前matrix[x][y]位置在旋转后的新位置便变为matrix[y][n-x-1]

参考文章:旋转矩阵
代码实现

class Solution {
public:
	void rotate(vector<vextor<int>>& matrix){
		int n = matrix.size();
		auto matrix_new = matrix;			// 这里的 = 拷贝值,将拷贝的值传给一个新的数组
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				matrix_new[j][n - i - 1] = matrix[i][j];
			}
		}
		matrix = matrix_new;
	}
};

时间复杂度为O(n2),空间复杂度为O(1)。

解法二:翻转替代旋转

不新构建一个数组的情况下,不能直接旋转得到数组。便通过间接的方式,先按对角线进行翻转,再按中位线进行翻转,最终得到目标矩阵。

原始矩阵A:
在这里插入图片描述在这里插入图片描述

当我们将矩阵以对角线为基准进行翻转时,可得到:
在这里插入图片描述 在这里插入图片描述

而我们的目标旋转矩阵的为:
在这里插入图片描述 C

可发现矩阵C和B的关系为对称翻转后的关系,即可通过将矩阵B以竖中位线来进行左右翻转,翻转后便可得到矩阵C。
在这里插入图片描述

同理,也可通过先将矩阵A2以横中位线为基准,将其进行上下翻转,得到矩阵B2再将矩阵B2以水平线反转,即可得到目标矩阵C。

参考文章:
秒懂系列!!!思路非常简单,代码也很易懂

代码实现

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        // 水平翻转
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < n; ++j) {
                swap(matrix[i][j], matrix[n - i - 1][j]);
            }
        }
        // 主对角线翻转
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                swap(matrix[i][j], matrix[j][i]);
            }
        }
    }
};

时间复杂度为O(n2),空间复杂度为O(1)

假设有一个 $n \times n$ 的二维数组 $matrix$,我们要将其顺时针旋转 $90$ 度,可以通过以下步骤实现: 1. 先将矩阵沿主对角线翻转,即将 $matrix[i][j]$ 与 $matrix[j][i]$ 交换。 2. 再将每一行沿中心线翻转,即将 $matrix[i][j]$ 与 $matrix[i][n-1-j]$ 交换。 代码如下: ```c++ void rotate(int** matrix, int matrixSize, int* matrixColSize){ // Step 1: 沿主对角线翻转 for(int i=0; i<matrixSize; i++){ for(int j=i; j<matrixSize; j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } // Step 2: 每一行沿中心线翻转 for(int i=0; i<matrixSize; i++){ for(int j=0; j<matrixSize/2; j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[i][matrixSize-1-j]; matrix[i][matrixSize-1-j] = temp; } } } ``` 在使用指针旋转的时候,我们需要将二维数组转化为一维指针,这里我们可以使用 $int* matrix$ 来表示二维数组,其中 $matrix[i][j]$ 可以表示为 $matrix[i \times n + j]$,其中 $n$ 表示矩阵的宽度或长度。 代码如下: ```c++ void rotate(int* matrix, int matrixSize, int* matrixColSize){ // Step 1: 沿主对角线翻转 for(int i=0; i<matrixSize; i++){ for(int j=i; j<matrixSize; j++){ int temp = *(matrix + i * matrixSize + j); *(matrix + i * matrixSize + j) = *(matrix + j * matrixSize + i); *(matrix + j * matrixSize + i) = temp; } } // Step 2: 每一行沿中心线翻转 for(int i=0; i<matrixSize; i++){ for(int j=0; j<matrixSize/2; j++){ int temp = *(matrix + i * matrixSize + j); *(matrix + i * matrixSize + j) = *(matrix + i * matrixSize + matrixSize - 1 - j); *(matrix + i * matrixSize + matrixSize - 1 - j) = temp; } } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值