大家好,我叫亓官劼(qí guān jié ),三本计算机在读,目前在积极准备21计算机考研中,同时也在学习后端开发,准备工作。不敢孤注一掷,因为要留条后路;不求两全其美在,因为那需要运气+机遇;只求学有所得,慢慢成长。CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~
每日一题 2020.04.07
难度 中等
给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
旋转矩阵应该是一个我们经常能看到的题目了,如果仅仅旋转矩阵,我们并不困难,这里使用一个辅助数组就可以进行轻松的实现,对于原数组matrix[i][j]
,我们复制一个新的数组copy[i][j]
,则我们旋转后copy[j][n - i - 1] = matrix[i][j];
,下面贴上完整的代码:
class Solution {
public:
void rotate(vector<vector>& matrix) {
int n = matrix.size();
auto copy = matrix;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
copy[j][n - i - 1] = matrix[i][j];
}
}
matrix = copy;
}
};
执行情况为;
在解法一中我们使用了额外的数组进行了一次复制,有的小伙伴发现题目中有个进阶的要求,就是不使用额外的空间来进行一个旋转,这时候我们上面的方法就不好用了,因为我们解法一种需要旋转时的中间状态,所以必须要一个数组进行复制状态。那我们该如何不使用额外空间来进行旋转呢?
这里我们可以使用两次翻转来完成旋转90度的操作,大家想想看,对于一个N*N的矩形,我们先上下旋转一次,在沿着对角线旋转一次(↘这个对角线哦!
),是不是正好是旋转了90!这个方法还更好写代码!下面就来看看代码吧:
class Solution {
public:
void rotate(vector<vector>& 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(1)的这种方法哦,在面试中经常会有这题,但是都会要求不使用额外的内存空间。