【代码练习】旋转矩阵题解思路记录分析

题目

给你一幅由 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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SmiledrinkCat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值