顺时针打印矩阵(编程题讲解)
顺时针打印矩阵
- 题目描述
- 题目分析
- python代码
- 使用python矩阵的旋转
- 矩阵的转置代码
- python旋转矩阵解法代码
《剑指offer》 编程题讲解。
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。
题目分析
最基础的解法就是什么技巧都不谈,也不考虑数据结构和算法的相关东西,无非就是考虑在编写代码的时候循环的边界条件,通常好的边界条件设置,可以减少循环判断的次数,甚至减少循环的执行次数。
大致分析一下,首先可以把任务分解成循环打印每一个圈的数据,每一个圈有四条边,然后打印多个圈就解决了这道题。编写代码的时候要注意测试用例的特殊情况,因为打印圈之后可能最后剩下的元素不构成一个圈了。这就又包括三种情况,四条边退化为一行,四条边退化为一列,四条边退化为一个元素,四条边退化为一个元素的可以归到前两种情况中处理。
《剑指offer》 书本里的处理是将三种情况放在最后判断,感兴趣的自行查阅相关资料。而我独立完成的做法略微有点不同,不过思路是类似的。我将判断条件纳入了循环之内,能够稍微的精简代码。每一圈仍然从(i,i)(i,i)(i,i)的位置开始顺时针打印,分四个子区域,两个行平行,两个列平行,这样在写代码的时候就不容易混乱。区域划分如下图,假设从(1,1)(1,1)(1,1)的位置开始打印。
在转圈的时候我让循环多执行一次,这样就把最后不足一个整圈的情况也纳入了循环中考虑。我把自己的python代码贴出来供大家参考。有什么疑问欢迎在下面留言讨论。
python代码
def printMatrix(self, matrix):res = []n = len(matrix)m = len(matrix[0])for o in range((min(m, n) + 1) // 1):# 这里加1,在行数/列数是奇数的时候让代码多执行一次res.extend([matrix[o][i] for i in range(o, m - o)])res.extend([matrix[j][m - 1 - o] for j in range(o + 1, n - o - 1)])if n - 1 - o > o:res.extend([matrix[n - 1 - o][m - i - 1] for i in range(o, m - o)])if m - 1 - o > o:res.extend([matrix[n - j - 1][o] for j in range(o + 1, n - o - 1)])return res
如果大家想进一步减少判断的次数,可以把循环中的两个判断拿出来放在循环外面。因为代码中每一个子循环严格的条件控制,即便外层循环多执行几次也不影响结果。
使用python矩阵的旋转
如果有一个矩阵,根据数学关系我们能知道,矩阵的旋转可以通过转置和翻转来实现,我们先来看以下的操作。
[1234]T=[1324]\left[ \begin{matrix} 1 & 2 \\ 3 & 4 \end{matrix} \right] ^T= \left[ \begin{matrix} 1 &3 \\ 2 & 4 \end{matrix} \right] [1324]T=[1234]
reverse([1324])=[2413]reverse\left( \left[ \begin{matrix} 1 &3 \\ 2 & 4 \end{matrix} \right] \right)= \left[ \begin{matrix} 2 & 4 \\ 1 &3 \\ \end{matrix} \right] reverse([1234])=[2143]
可以证明矩阵的逆时针旋转就是先对矩阵转置,然后翻转。
reverse([1234])=[3412]reverse\left( \left[ \begin{matrix} 1 &2 \\ 3 & 4 \end{matrix} \right] \right)= \left[ \begin{matrix} 3 & 4 \\ 1 &2 \\ \end{matrix} \right] reverse([1324])=[3142]
[3412]T=[3142]\left[ \begin{matrix} 3 & 4 \\ 1 &2 \\ \end{matrix} \right] ^T= \left[ \begin{matrix} 3&1 \\ 4 & 2 \end{matrix} \right] [3142]T=[3412]
可以证明矩阵的顺时针旋转就是先对矩阵翻转,然后转置。
我们可以很快的写出矩阵的转置代码,就是对矩阵中(i,j)(i,j)(i,j)和(j,i)(j,i)(j,i)不停的对换即可。代码如下
矩阵的转置代码
def transpose(matrix):for i in range(len(matrix)):for j in range(i + 1, len(matrix)):matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
当然这是方阵的类型,如果不是方阵就得开辟空间,然后一列一列的加入。我们直接给出python的简化代码。
操作 | 代码 |
---|---|
转置 | matrix[:]=map(list,zip(*matrix)) |
顺时针旋转 | matrix[:] = map(list,zip(*matrix[::-1])) |
逆时针旋转 | matrix =list(map(list,zip(*matrix)))[::-1] |
熟悉了以上操作,这道题的代码就可以简单很多,我们可以考虑拿出矩阵的第0行加入到打印的队列里,同时把矩阵中的第0行删除,这个时候需要打印右边的一列,可以把矩阵逆时针旋转,最后一列就变成了第一行,然后重复。这样就用矩阵的转圈代替了打印变量的转圈。算法难想,但是代码简单。
python旋转矩阵解法代码
def printMatrix(matrix):matrix = matrix.copy() # 拷贝一份,防止修改改变原来的数据result = []while (matrix):result += matrix.pop(0)matrix = list(map(list, zip(*matrix)))[::-1]return result
很显然第一种方式的实现要比第二种方式实现起来复杂一些,但是效率很高,即便是换做其他语言,改动也不是很大,但是循环复杂,循环条件多,容易出错,第二种方式思路复杂,想出来需要有一定的技巧,而且要有编码基础,但是运行效率低,需要对不停地开辟空间来拷贝旋转的数组,当问题的规模非常大的时候,第二种方式的开销将是巨大的。
顺时针打印矩阵(编程题讲解)相关推荐
- php 顺时针打印矩阵,这题
浅谈狄利克雷相关题目套路2021-03-25 21:58:20 啥都不知道,被yyc D爆了/kk 扔道题 P2714 四元组统计 乍一看,就想推式子,结果发现自己是个憨批 莫反就两条式子 考虑第二种 ...
- java程序输出矩阵_java编程题之顺时针打印矩阵
本文实例为大家分享了java顺时针打印矩阵的具体代码,供大家参考,具体内容如下 import java.util.ArrayList; /** * * 剑指offer编程题(JAVA实现)--第19题 ...
- 【算法刷题日记之本手篇】左右最值最大差与顺时针打印矩阵
⭐️前面的话⭐️ 本篇文章介绍来自牛客试题广场的两道题题解,分别为[左右最值最大差]和[顺时针打印矩阵],展示语言java. 小贴士:本专栏所有题目来自牛客->面试刷题必用工具
- 程序员面试题精选100题(51)-顺时针打印矩阵
// 程序员面试题精选100题(51)-顺时针打印矩阵.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostre ...
- 剑指Offer(十九):顺时针打印矩阵
剑指Offer(十九):顺时针打印矩阵 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...
- 【剑指offer】顺时针打印矩阵
转载请注明出处:http://blog.csdn.net/ns_code/article/details/26053049 剑指offer上的第20题,九度OJ上測试通过. 题目描写叙述: 输入一个矩 ...
- 《LeetCode力扣练习》剑指 Offer 29. 顺时针打印矩阵 Java
<LeetCode力扣练习>剑指 Offer 29. 顺时针打印矩阵 Java 一.资源 题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matr ...
- 【剑指offer-Java版】20顺时针打印矩阵
顺时针打印矩阵:重在理解,毕竟作者分析的那个方法看起来还是蛮复杂的-所以自己写了个接地气的方法 重在逻辑的一个题,一次性完全写对还是比较困难的 public class _Q20 {public vo ...
- 【完整可运行代码】剑指 Offer 29. 顺时针打印矩阵
立志用最少的代码做最高效的表达 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2, ...
最新文章
- java代码代替xml实现图片
- Redis 4.x/5.x未授权访问漏洞
- eclipse没有dynamic web project_Microsoft Teams迎来Project与Roadmap功能集成
- Linux 技巧: 从命令行创建像素标尺
- so库调用java函数_linux下so动态库调用主程序函数
- python基础之异常处理、面向对象
- mysql skip-opt_FAQ系列 | mysqldump选项之skip-opt-阿里云开发者社区
- 进入多个页签_俄罗斯学生落地签如何办理?
- 高考计算机专业最低分数线是多少,2021最低多少分可以稳上二本 高考二本分数线是多少...
- java socket 异步回调函数_浅谈socket同步和异步、阻塞和非阻塞、I/O模型
- python数据结构与算法知识点_数据结构和算法基础知识点(示例代码)
- ajax返回的java list_ssm+ajax异步请求返回list遍历
- ipad pro + zotero + 坚果云 + PDF Expert 搭建多平台文献管理(自用备忘)
- 微信朋友圈装x代码_朋友圈生成器有哪些_微信朋友圈生成器大全_微信朋友圈装逼生成器下载_飞翔软件专题...
- Delphi 2007 体验
- lbs多城市切换php源码,多省份多城市多区县切换 专业版(dicky_multicityswitch) dz插件分享,可以随意切换到其它地区分站功能...
- 情情の日安的个人介绍
- AD域和LDAP协议
- 来说下华为专属分享功能——Huawei Share2.0
- Golang分布式应用之etcd
热门文章
- linux客户端交互,客户端交互性
- 循环冗余校验码CRC原理和实例
- HDCTF-2nd复盘
- Mac电脑Safari 浏览器中Cookie 和网站数据如何管理
- UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xca in position 24: invalid continuation byte
- mojave时间机器文件服务器,在 Mac 上可以与时间机器配合使用的磁盘类型
- RGB565,RGB8888等相关
- 小白兔写话_可爱的小白兔二年级写话
- ntohs和htons区别?
- 【C语言】字符串函数详解