将正方形矩阵顺时针转动90度

本文介绍了一种在额外空间复杂度为O(1)的情况下,将N*N矩阵顺时针旋转90度的方法。通过分圈处理的方式,每次处理一个子矩阵的最外层,实现了矩阵的有效旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:给定一个N*N的矩阵matrix,求把这个矩阵调整成顺时针转动90度后的形式。

例如:

1     2    3    4

5     6    7    8

9    10  11  12

13  14  15  16

顺时针转动90度后为:

13    9    5   1

14   10   6   2

15   11   7   3

16   12   8   4

要求:额外空间复杂度为O(1)

解答:

这里任然使用分圈处理的方式,在矩阵中用左上角的坐标(tr,tc)和右下角的坐标(dr,dc)就可以表示一个子矩阵。题目中的矩阵,当(tr,tc)=(0,0)、(dr,dc)=(3,3)时,表示的子矩阵就是整个矩阵,这个子矩阵最外层的部分如下:

1   2   3   4

5             8

9            12

13 14 15 16 

在这个外圈中,1,4,16,13为一组,然后1占据4的位置,4占据16的位置,16占据13的位置,13占据1的位置,一组就调完了。然后2,8,15,9为一组,继续调整的过程,最后3,12,14,5为一组,继续占据调整过程。然后(tr,tc)=(0,0)、(dr,dc)=(3,3)的子矩阵外层调整完毕。接下来令tr和tc加1,(tr,tc)=(1,1),令dr,dc减1,即(dr,dc)=(2,2),此时表示的子矩阵如下.

6       7

10    11

这个外层只有一组,占据调整之后就可以了。所以如果子矩阵的大小是M*M,一共就有M-1组,分别进行调整即可。

具体过程请参看如下代码的rotate方法:

 1 public void rotate(int[][] matrix)
 2 
 3 {
 4 
 5    int tr=0;
 6 
 7    int tc=0;
 8 
 9    int dr=matrix.length-1;
10 
11    int dc=matrix[0].length-1;
12 
13    while(tr<dr)
14 
15       rotateEdge(matrix,tr++,tc++,dr--,dc--);
16 
17 }
18 
19  
20 
21 public void rotateEdge(int[][] m,int tr,int tc,int dr,int dc)
22 
23 {
24 
25     int times=dc-tc;
26 
27     int tmp=0;
28 
29     for(int i=0;i!=times;i++)
30 
31   {
32 
33      tmp=m[tr][tc+i];
34 
35      m[tr][tc+i]=m[dr-i][tc];
36 
37      m[dr-i][tc]=m[dr][dc-i];
38 
39      m[dr][dc-i]=m[tr+i][dc];
40 
41      m[tr+i][dc]=tmp;
42 
43    }
44 
45 }
46 
47  
View Code

 

转载于:https://www.cnblogs.com/guanling222/p/5770443.html

### 实现正方形矩阵顺时针旋转90 为了实现一个正方形矩阵顺时针旋转90操作,可以采用两种主要方法:一种是创建一个新的矩阵来存储旋转后的结果;另一种是在原地进行旋转。下面分别介绍这两种方式。 #### 方法一:使用额外空间的新矩阵 这种方法较为直观简单,在原有基础上构建新的矩阵用于保存旋转之后的数据。通过遍历原始数组并按照特定规律映射到新位置上完成整个过程[^2]。 ```cpp #include <iostream> using namespace std; int main() { int n; cin >> n; // 定义两个二维数组,一个是源数据a[][],另一个是用来存放下一步计算的结果b[][] int a[201][201], b[201][201]; // 输入矩阵元素 for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cin >> a[i][j]; } } // 将矩阵逆序列方向读取赋值给目标矩阵对应行的位置 for (int j = n - 1; j >= 0; --j) { for (int i = 0; i < n; ++i) { b[i][n - 1 - j] = a[j][i]; } } // 输出转换后的矩阵 for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cout << b[i][j] << " "; } cout << endl; } return 0; } ``` 此段代码实现了利用辅助矩阵`b[][]`来进行矩阵旋转的功能。对于每一个位于`(row, col)`处的元素来说,它会被移动至`(col, newRowSize-row-1)`这个新坐标点上去。 #### 方法二:不使用额外空间的原地旋转 如果希望节省内存开销,则可以选择直接在原来的矩阵内部调整各个元素之间的相对关系从而达到同样的效果。这种方式虽然稍微复杂一点但是效率更高一些因为不需要额外分配大量的连续内存块[^1]。 以下是具体的实现思路: 1. 对于每一圈(即最外面一层),依次交换四个角上的数值; 2. 同样地处理该圈内的其他所有相邻单元格直到这一层完全翻转完毕; 3. 继续向内推进重复上述两步直至所有的层次都被处理过为止。 下面是基于以上逻辑编写的C++程序片段: ```cpp void rotateInPlace(vector<vector<int>>& matrix) { const size_t N = matrix.size(); if (!N || !matrix[0].size()) return ; for(size_t layer = 0; layer < N / 2; ++layer){ size_t first = layer; size_t last = N - 1 - layer; for(size_t i = first; i < last; ++i){ size_t offset = i - first; // Save top. int top = matrix[first][i]; // left -> top matrix[first][i] = matrix[last-offset][first]; // bottom -> left matrix[last-offset][first] = matrix[last][last - offset]; // right - offset] = matrix[i][last]; // top -> right matrix[i][last] = top; } } } // 测试函数调用部分省略... ``` 这段代码展示了如何在一个已知大小为 `NxN` 的方阵中执行就地旋转变换的操作。注意这里假设输入的是合法且完整的矩形区域,并且已经包含了必要的边界条件判断语句以防止越界访问等问题的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值