前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >leetcode: explore-array-31 旋转矩阵

leetcode: explore-array-31 旋转矩阵

作者头像
用户7685359
发布2020-08-24 16:22:11
4390
发布2020-08-24 16:22:11
举报
文章被收录于专栏:FluentStudy

leetcode explore 初级算法第十一题。

题目分析

这里把题目贴出来:

代码语言:javascript
复制
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: 不能新定义一个二维矩阵做为中间变量

这里有点小投机的是,题目中说的是不能新定义一个二维矩阵,不是说不能去新开辟空间,所以一度程序上是有简化的。

代码实现

规律很容易得出来,难得是不能定义一个新的二维矩阵,所以这里先生成一个目标的一维矩阵,然后通过一定规律再依次赋值给原矩阵。代码如下:

代码语言:javascript
复制
"""
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 页面,看了一些别人的写法,思路比较清晰也比较通用,解决方法即通过多次转换:

代码语言:javascript
复制
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],
]

按照上面的思路,可以用一句话解决,代码如下

代码语言:javascript
复制
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 实现如下:

代码语言:javascript
复制
matrix[::] = [[row[i] for row in matrix] for i in range(len(matrix[0]))][::-1]

点击查看原文可进入题目

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FluentStudy 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目分析
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档