leetcode explore 初级算法第十一题。
这里把题目贴出来:
You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Note:
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:
Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
rotate the input matrix in-place such that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
Example 2:
Given input matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
rotate the input matrix in-place such that it becomes:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
题目是英文的,但是看这个题目英文理解起来也不是很困难。关键词: 1、matrix: 矩阵 2、2D matrix: 二维矩阵 3、rotate: 旋转 4、clockwise: 顺时针 5、90 degrees: 90度
即:我们需要将一个二维矩阵顺时针旋转90度。 理解题意之后,我们还需要关注下题目中额外的要求,即 note 部分,关键词: 1、in-place: 原地修改 2、do not allocate another 2D matrix: 不能新定义一个二维矩阵做为中间变量
这里有点小投机的是,题目中说的是不能新定义一个二维矩阵,不是说不能去新开辟空间,所以一度程序上是有简化的。
规律很容易得出来,难得是不能定义一个新的二维矩阵,所以这里先生成一个目标的一维矩阵,然后通过一定规律再依次赋值给原矩阵。代码如下:
"""
https://leetcode.com/problems/rotate-image/submissions/
解题思路:
转换规律是:
matrix[row][col] 转换后的位置为 matrix[col][total_row - 1 - row]
这里的 row 与 col 均从 0 开始计算
因为只能原地修改原二维矩阵,也不能重新分配一个新的二维矩阵,
所以投机了一下,先生成了一个和目标矩阵顺序的一维矩阵,
然后循环取值赋值给原二维矩阵
举例如下:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
real_matrix = [7, 4, 1, 8, 5, 2, 9, 6, 3]
赋值规律:
matrix[row][col] = real_matrix[row*total_row+col]
"""
class Solution:
def rotate(self, matrix):
total_row = len(matrix)
real_matrix = [matrix[col][total_row - 1 - row] for row in range(total_row -1, -1, -1) for col in range(total_row - 1, -1, -1)]
# matrix[::] = [m[i*total_row:total_row+i*total_row] for i in range(total_row)]
# 上面一行代码等于下面三行代码
# 不能使用 matrix = [...],因为这相当于是重新分配空间,而 matrix[::] 是在原列表上做修改
for row in range(total_row):
for col in range(total_row):
matrix[row][col] = real_matrix[row*total_row+col]
# 测试
if __name__ == '__main__':
s = Solution()
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print("before rotate: {}".format(matrix))
s.rotate(matrix)
print("after rotate: {}".format(matrix))
其他方法 在 leetcode-discuss 页面,看了一些别人的写法,思路比较清晰也比较通用,解决方法即通过多次转换:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
=> 倒序
_temp = [
[7, 8, 9],
[4, 5, 6],
[1, 2, 3],
]
=> 行转列
target_matrix = [
[7, 4, 1],
[8, 5, 2],
[9, 6, 3],
]
按照上面的思路,可以用一句话解决,代码如下
matrix[::] = [[row[i] for row in matrix[::-1]] for i in range(len(matrix[0]))]
"""
分析如下:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[row[i] for row in matrix[::-1]]
首先 [row for row in matrix[::-1]]
执行结果为 _temp = [[7, 8, 9], [4, 5, 6], [1, 2, 3]]
外层循环 i 从 0 开始,相当先取 _temp 第0列的值,赋值给第0行,依次得到结果
"""
扩展
上面的解题思路,不仅试用于顺时针,也适用于逆时针,可参考 A common-method。即:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
=> 行转列
_temp = [
[1, 4, 7],
[2, 5, 8],
[3, 6, 9]
]
=> 倒序
target_matrix = [
[3, 6, 9],
[2, 5, 8],
[1, 4, 7]
]
Python 实现如下:
matrix[::] = [[row[i] for row in matrix] for i in range(len(matrix[0]))][::-1]
点击查看原文可进入题目