旋转矩阵

旋转矩阵

一、题目

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

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

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
给定 matrix = 
[
[1,2,3],
[4,5,6],
[7,8,9]
],

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

Leetcode:https://leetcode.cn/problems/rotate-matrix-lcci/

Leetcode:https://leetcode.cn/problems/spiral-matrix

二、思路

和转圈打印矩阵的思路一致,我们用两个坐标作为基准,即左上角的坐标和右下角的坐标。用这两个坐标可以确定矩阵的一圈。当更新完这一圈之后,我们再将左上角的横纵坐标都加一,右下角的横纵坐标都减一,获取到更里层的一圈。直到左上角的指标等于右下角的指标。注意题目是 N*N 的矩阵,所以如果左上角坐标等于右下角坐标时,就不用再旋转了。

那么如何旋转矩阵的一圈呢?我们发现对于 N*N 的一圈,我们只需要旋转 N-1 次即可。比如 4*4 的矩阵,我们以最外圈举例子。第一次,我们需要进行

1
2
3
4
(0, 0) -> (0, 3)
(0, 3) -> (3, 3)
(3, 3) -> (3, 0)
(0, 0) -> (3, 0)

所以我们先保存 (0, 0) 位置的元素,然后让(3, 0) 先赋给 (0, 0),然后依次旋转。接下来是 (0, 1)、(0, 2)。一圈我们变化 3 次。

重点是如何表示坐标,如下的代码较为清晰。

三、代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <vector>
#include <iostream>

class Solution {
public:
void rotate(std::vector<std::vector<int>>& matrix) {
if (matrix.empty()) {
return;
}
int lu_row = 0, lu_line = 0;
int rd_row = matrix.size()-1, rd_line = matrix[0].size()-1;
for (; lu_row < rd_row && lu_line < rd_line;) {
rotate_edge(matrix, lu_row++, lu_line++, rd_row--, rd_line--);
}
}

private:
void rotate_edge(std::vector<std::vector<int>>& matrix, int lu_row, int lu_line, int rd_row, int rd_line) {
int count = rd_row - lu_row;
int tmp = 0;
for (int i = 0; i < count; ++i) {
tmp = matrix[lu_row][lu_line+i];
matrix[lu_row][lu_line+i] = matrix[rd_row-i][lu_line];
matrix[rd_row-i][lu_line] = matrix[rd_row][rd_line-i];
matrix[rd_row][rd_line-i] = matrix[lu_row+i][rd_line];
matrix[lu_row+i][rd_line] = tmp;
}
}
};

void print_matrix(const std::vector<std::vector<int>>& matrix) {
for (size_t i = 0; i < matrix.size(); ++i) {
for (size_t j = 0; j < matrix[i].size(); ++j) {
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}

int main() {
Solution s;
std::vector<std::vector<int>> matrix{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
s.rotate(matrix);
print_matrix(matrix);
return 0;
}

时间复杂度 O(N*N),空间复杂度 O(1)