leetcode: explore-array-31 旋转矩阵

时间:2022-07-23
本文章向大家介绍leetcode: explore-array-31 旋转矩阵,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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]

点击查看原文可进入题目