Python面试宝典第34题:旋转图像

题目

给定一个n × n的二维矩阵matrix表示一个图像,请你将图像顺时针旋转90度。

注意:你必须在原地旋转图像。这意味着,你需要直接修改输入的二维矩阵,而不能使用另一个矩阵来旋转图像。

示例 1:

python 复制代码
输入:matrix = [[1,2,3], [4,5,6], [7,8,9]]
输出:[[7,4,1], [8,5,2], [9,6,3]]

示例 2:

python 复制代码
输入: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 + 1) / 2,其中n是矩阵的大小。这是因为对于一个n × n的矩阵,最外层包含4 * n - 8个元素(不考虑角点元素,只考虑边上的元素),次外层(如果存在的话)包含4 * (n - 2) - 8个元素,依此类推。

2、层旋转。对于每一层,从外层到内层,将四个角依次旋转到新的位置。我们遍历每一层的边界,将四个角的值依次交换到新的位置。

3、角交换。在每一层中,我们保存左上角的值,然后按照顺时针方向依次交换四个角的位置。

根据上面的算法步骤,我们可以得出下面的示例代码。

python 复制代码
def rotate_image_by_layer_iteration(matrix):
    n = len(matrix)
    # 确定层数
    layers = (n + 1) // 2
    
    for layer in range(layers):
        start = layer
        end = n - 1 - layer
        # 遍历每一层的边界
        for i in range(start, end):
            offset = i - start
            # 保存左上角的值
            top = matrix[start][i]
            # 左上角 <- 左下角
            matrix[start][i] = matrix[end - offset][start]
            # 左下角 <- 右下角
            matrix[end - offset][start] = matrix[end][end - offset]
            # 右下角 <- 右上角
            matrix[end][end - offset] = matrix[i][end]
            # 右上角 <- 左上角
            matrix[i][end] = top

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
rotate_image_by_layer_iteration(matrix)
print(matrix)

matrix = [[5, 1, 9, 11], [2, 4, 8, 10], [13, 3, 6, 7], [15, 14, 12, 16]]
rotate_image_by_layer_iteration(matrix)
print(matrix)

两次转置法

顾名思义,两次转置法的基本思想为:首先进行一次转置,然后将每一行逆序。第一次转置将矩阵沿着主对角线进行转置,即将矩阵的行变为列,列变为行。第二次转置将转置后的矩阵的每一行进行逆序操作,即得到顺时针旋转90度后的矩阵。使用两次转置法求解本题的主要步骤如下。

1、转置矩阵。遍历矩阵的上半部分,将每个元素与其对称位置的元素交换。

2、逆序行。遍历转置后的矩阵的每一行,并将其逆序。

根据上面的算法步骤,我们可以得出下面的示例代码。

python 复制代码
def rotate_image_by_two_transpositions(matrix):
    n = len(matrix)
    
    # 转置矩阵
    for i in range(n):
        for j in range(i, n):
            matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
    
    # 逆序行
    for i in range(n):
        matrix[i].reverse()

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
rotate_image_by_two_transpositions(matrix)
print(matrix)

matrix = [[5, 1, 9, 11], [2, 4, 8, 10], [13, 3, 6, 7], [15, 14, 12, 16]]
rotate_image_by_two_transpositions(matrix)
print(matrix)

总结

对于一个n × n的矩阵,使用层迭代法时,每一层需要遍历一定数量的元素进行交换。外层的元素数量为4 * (n - 2),次外层为4 * (n - 4),依此类推,直到中心元素。因此,层迭代法的总体时间复杂度为O(n^2)。对于初学者来说,理解每一层如何处理以及如何交换元素可能会稍微复杂一些。

使用两次转置法时,转置矩阵需要遍历每个元素一次,故第一次转置的时间复杂度为O(n^2),第二次转置(即行的反转)的时间复杂度也为O(n^2)。因此,两次转置法的总体时间复杂度为O(n^2)。两次转置法虽然简单,但它需要两次遍历矩阵,这可能在某些情况下被认为是一种额外的开销。

相关推荐
爱吃生蚝的于勒8 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~11 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
进击的六角龙33 分钟前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
王哈哈^_^36 分钟前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城39 分钟前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
一只爱好编程的程序猿1 小时前
Java后台生成指定路径下创建指定名称的文件
java·python·数据下载
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
Aniay_ivy1 小时前
深入探索 Java 8 Stream 流:高效操作与应用场景
java·开发语言·python
gonghw4031 小时前
DearPyGui学习
python·gui