48. Rotate Image (M)
https://leetcode.com/problems/rotate-image/
Last updated
https://leetcode.com/problems/rotate-image/
Last updated
You are given an n x n
2D matrix
representing an image, rotate the image by 90 degrees (clockwise).
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
Example 1:
Example 2:
Constraints:
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
题目很好理解,就是让你将一个二维矩阵顺时针旋转 90 度,难点在于要「原地」修改,函数签名如下:
如何「原地」旋转二维矩阵?稍想一下,感觉操作起来非常复杂,可能要设置巧妙的算法机制来「一圈一圈」旋转矩阵:
但实际上,这道题不能走寻常路,在讲巧妙解法之前,我们先看另一道谷歌曾经考过的算法题热热身:
给你一个包含若干单词和空格的字符串 s
,请你写一个算法,原地反转所有单词的顺序。
比如说,给你输入这样一个字符串:
你的算法需要原地反转这个字符串中的单词顺序:
常规的方式是把 s
按空格 split
成若干单词,然后 reverse
这些单词的顺序,最后把这些单词 join
成句子。但这种方式使用了额外的空间,并不是「原地反转」单词。
正确的做法是,先将整个字符串 s
反转:
然后将每个单词分别反转:
这样,就实现了原地反转所有单词顺序的目的。
我讲这道题的目的是什么呢?
旨在说明,有时候咱们拍脑袋的常规思维,在计算机看来可能并不是最优雅的;但是计算机觉得最优雅的思维,对咱们来说却不那么直观。也许这就是算法的魅力所在吧。
回到之前说的顺时针旋转二维矩阵的问题,常规的思路就是去寻找原始坐标和旋转后坐标的映射规律,但我们是否可以让思维跳跃跳跃,尝试把矩阵进行反转、镜像对称等操作,可能会出现新的突破口。
我们可以先将 n x n
矩阵 matrix
按照左上到右下的对角线进行镜像对称:
然后再对矩阵的每一行进行反转:
发现结果就是 matrix
顺时针旋转 90 度的结果:
将上述思路翻译成代码,即可解决本题:
肯定有读者会问,如果没有做过这道题,怎么可能想到这种思路呢?
其实我觉得这个思路还是挺容易想出来的,如果学过线性代数,这道算法题的思路本质就是矩阵变换,肯定可以想出来。
即便没学过线性代数,旋转二维矩阵的难点在于将「行」变成「列」,将「列」变成「行」,而只有按照对角线的对称操作是可以轻松完成这一点的,对称操作之后就很容易发现规律了。
既然说道这里,我们可以发散一下,如何将矩阵逆时针旋转 90 度呢?
思路是类似的,只要通过另一条对角线镜像对称矩阵,然后再反转每一行,就得到了逆时针旋转矩阵的结果:
翻译成代码如下:
至此,旋转矩阵的问题就解决了。