旋转数组(顺时针90度,180度,270度)

旋转数组(90 ∘ ^{\circ} ,180 ∘ ^{\circ} ,270 ∘ ^{\circ}

  1. 顺时针旋转90 ∘ ^{\circ}

    第一种是用坐标变换法,在网上看到的一种坐标变换:

    顺时针90 ∘ ^{\circ} newArr[i][j]=arr[N-1-j][i]

    顺时针180 ∘ ^{\circ} newArr[i][j]=arr[N-1-i][N-1-j]

    顺时针270 ∘ ^{\circ} newArr[i][j]=arr[j][N-1-i]

    第二种根据特点,先观察matrix与转置后的matrix与顺时针旋转90 ∘ ^{\circ}

    1. 原矩阵
    123
    456
    789
    1. 转置
    147
    258
    369
    1. 旋转90 ∘ ^{\circ}
    741
    852
    963

    观察可知,转置后矩阵每行反转即得到顺时针旋转90 ∘ ^{\circ} 的矩阵,故可用以下代码实现:

    def rotate90(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()
        return matrix
    

    第三种方法,使用函数式编程的方法,其实顺时针旋转90 ∘ ^{\circ} 等价于先将原来的矩阵上下翻转然后再转置,逆时 针旋转90 ∘ ^{\circ} 等价于先将原来的矩阵转置再上下翻转。这个过程可以用表格演示一下:

    1)先上下翻转再转置等价于顺时针旋转90 ∘ ^{\circ}

    上下翻转

    789
    456
    123

    转置

    741
    852
    963

    2) 先转置再上下翻转等价于逆时针旋转90 ∘ ^{\circ}

    转置

    147
    258
    369

    上下翻转

    369
    258
    147

    这个其实就是逆时针旋转90 ∘ ^{\circ}

    既然前面讲了可以通过先转置再左右翻转的方法实现顺时针旋转90 ∘ ^{\circ} ,为什么又要讲这种方法呢?老实地说是因为我看到大神这么写,代码很简洁,就贴在这儿,加点自己的分析,23333。

    好了,言归正传。python中矩阵是按行存储的,所以对于二维矩阵来说,实现上下翻转很简单:matrix=matrix[::-1],转置的话可以用zip(*matrix)来实现。
    此处补充一下,zip(*matrix)为什么能实现转置,首先,假设matrix的形状是n*m的,*matrixmatrix矩阵分解为n个长度为m的列表,然后zip依次取这些列表的各个元素构成m个长度为n的元组,故它可实现转置。
    举个例子,matrix=[[1,2,3],[4,5,6]*matrix将其变成[1,2,3],[4,5,6]再传给zipzip之后结果为(1,4),(2,5),(3,6)。可见实现了转置。

    具体代码:

    def rotate90(matrix):
        # matrix[:] = map(list,zip(*matrix[::-1])) # 这种方法是原地修改,会修改传入的矩阵
        matrix = list(map(list,zip(*matrix[::-1]))) # 这种方法不是原地修改,对原来矩阵无影响
        return matrix
    

    以上代码解读:

    1. matrix[::-1]为将矩阵上下翻转
    2. zip(*matrix[::-1])中,*将翻转矩阵解压成N个列表,然后使用zip使这些列表变成N个分别含有各行的第1-N个元素的元组
    3. map(list,..)使前面的结果重新变成列表
    4. matrix=[[1,2,3],[4,5,6],[7,8,9]]为例
    5. matrix[::-1]=[[7,8,9],[4,5,6],[1,2,3]]
    6. zip(*matrix[::-1])matrix[::-1]先解成三个列表[7,8,9],[4,5,6],[1,2,3],然后对这三个列表使用zip,生成一个zip对象,里面是三个元组(7,4,1),(8,5,2),(9,6,3)
    7. map(list,...)将上述三个元组变为列表,再通过list方法把它们由map对象变成列表
    8. 因此matrix = list(map(list,zip(*matrix[::-1])))得到的是顺时针旋转90 ∘ ^{\circ} 后的矩阵

    至于顺时针旋转180 ∘ ^{\circ} ,其实就是先上下翻转,再左右翻转;而顺时针旋转270 ∘ ^{\circ} 即为逆时针旋转90 ∘ ^{\circ} ,它们的代码分别贴下:

    def rotate180(matrix):
        N = len(matrix)
        matrix = matrix[::-1]
        for i in range(N):
            matrix[i] = list(reversed(matrix[i]))  # 这一步不用matrix[i].reverse()是为了防止对原数组的各行进行翻转
        return matrix
    
    def rotate270(matrix):
        matrix = list(map(list,zip(*matrix)))[::-1]
        return matrix
    

    在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值