题目
给你一幅由 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]
]
题解1
思路
首先第一反应是新建一个N维矩阵,倒序将一维数组按列填入新矩阵中,代码如下。
代码
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
n = len(matrix)
for i in range(n):
res = [[0 for x in range(n)] for y in range(n)]
print(res) # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for j in range(n):
ls = matrix.pop()
for k in range(n):
print(ls[k])
res[k][j] = ls[k]
# print(res, res[k][j])
return res
复习知识点
知识点1.初始化固定长度为n的空列表
方法一:使用for循环和append()
arr = []
for i in range(n):
arr.append(0)
方法二:使用列表推导
用列表推导可以编写高效率的代码,它的执行速度比for循环快35%
arr = [0 for i in range(n)]
方法三:使用*运算符
运算符可以用作[object] * n,其中n是数组中元素的数目:
arr = [0]*n
知识点2.获取列表最后一个值
方法一:使用索引,仅获得,不改变列表
numbers = [1, 2, 3, 4, 5]
# 打印最后一个元素
print(numbers[-1])
方法二:使用pop(),获得的同时列表移除最后一个元素
numbers = [1, 2, 3, 4, 5]
# 打印最后一个元素
print(numbers.pop())
题解2
思路
仔细阅读题目可知,该题不希望使用额外空间,仅进行矩阵内部值的交换
如何进行交换呢?
以四维矩阵为例,需从图左转换到图右。
首先进行上下翻转,得到如下矩阵
可发现左对角线已完成90°旋转,只需将对角线两侧两两交换即可得到想要的矩阵。
对角线两侧互换时可理解为若干个正方形两条边互换,第一个正方形以[0][0]为顶角,第二个正方形以[1][1]为顶角,以此类推,得到一个i * j的循环,进行交换即可。
代码
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
# 1.翻转列表
matrix.reverse() # 此时对角线已归位
# 2.左对角线两侧互换
for i in range(len(matrix)):
for j in range(i, len(matrix)):
temp = matrix[i][j]
matrix[i][j] = matrix[j][i]
matrix[j][i] = temp
复习知识点
知识点3.列表翻转
方法一:reverse()方法,无返回值,原地翻转
a = [1, 2, 3, 4, 5, 6, 7, 'a', 'b']
a.reverse()
print('列表反转结果:', a) # [‘b’, ‘a’, 7, 6, 5, 4, 3, 2, 1]
方法二:内置reversed()函数
内置函数reversed()函数不对原列表做任何修改,而是返回一个逆序排列后的迭代对象,得到的结果需转换成列表
a = [1, 2, 3, 4, 5, 6, 7, 'a', 'b']
a1 = reversed(a)
print('列表反转结果(迭代对象):', a1) # <list_reverseiterator object at 0x00000243EF467A20>
print('列表反转结果转换成列表:', list(a1)) # [‘b’, ‘a’, 7, 6, 5, 4, 3, 2, 1]
方法三:列表切片
list[x:y:z]
x:切片开始位置,默认为0
y:切片截止(但不包含)位置,默认为列表长度
z:切片的步长,默认为1;-1则表示从最后元素开始切片
# 切片实现反转
a = [1, 2, 3, 4, 5, 6, 7, 'a', 'b']
print('列表反转结果:', a[::-1]) # [‘b’, ‘a’, 7, 6, 5, 4, 3, 2, 1]