顺时针打印矩阵

  • 题目描述
  • 题目分析
    • 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] [13​24​]T=[12​34​]
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([12​34​])=[21​43​]
  可以证明矩阵的逆时针旋转就是先对矩阵转置,然后翻转。
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([13​24​])=[31​42​]
[3412]T=[3142]\left[ \begin{matrix} 3 & 4 \\ 1 &2 \\ \end{matrix} \right] ^T= \left[ \begin{matrix} 3&1 \\ 4 & 2 \end{matrix} \right] [31​42​]T=[34​12​]
  可以证明矩阵的顺时针旋转就是先对矩阵翻转,然后转置。
  我们可以很快的写出矩阵的转置代码,就是对矩阵中(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

  很显然第一种方式的实现要比第二种方式实现起来复杂一些,但是效率很高,即便是换做其他语言,改动也不是很大,但是循环复杂,循环条件多,容易出错,第二种方式思路复杂,想出来需要有一定的技巧,而且要有编码基础,但是运行效率低,需要对不停地开辟空间来拷贝旋转的数组,当问题的规模非常大的时候,第二种方式的开销将是巨大的。

顺时针打印矩阵(编程题讲解)相关推荐

  1. php 顺时针打印矩阵,这题

    浅谈狄利克雷相关题目套路2021-03-25 21:58:20 啥都不知道,被yyc D爆了/kk 扔道题 P2714 四元组统计 乍一看,就想推式子,结果发现自己是个憨批 莫反就两条式子 考虑第二种 ...

  2. java程序输出矩阵_java编程题之顺时针打印矩阵

    本文实例为大家分享了java顺时针打印矩阵的具体代码,供大家参考,具体内容如下 import java.util.ArrayList; /** * * 剑指offer编程题(JAVA实现)--第19题 ...

  3. 【算法刷题日记之本手篇】左右最值最大差与顺时针打印矩阵

    ⭐️前面的话⭐️ 本篇文章介绍来自牛客试题广场的两道题题解,分别为[左右最值最大差]和[顺时针打印矩阵],展示语言java. 小贴士:本专栏所有题目来自牛客->面试刷题必用工具

  4. 程序员面试题精选100题(51)-顺时针打印矩阵

    // 程序员面试题精选100题(51)-顺时针打印矩阵.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostre ...

  5. 剑指Offer(十九):顺时针打印矩阵

    剑指Offer(十九):顺时针打印矩阵 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...

  6. 【剑指offer】顺时针打印矩阵

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26053049 剑指offer上的第20题,九度OJ上測试通过. 题目描写叙述: 输入一个矩 ...

  7. 《LeetCode力扣练习》剑指 Offer 29. 顺时针打印矩阵 Java

    <LeetCode力扣练习>剑指 Offer 29. 顺时针打印矩阵 Java 一.资源 题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matr ...

  8. 【剑指offer-Java版】20顺时针打印矩阵

    顺时针打印矩阵:重在理解,毕竟作者分析的那个方法看起来还是蛮复杂的-所以自己写了个接地气的方法 重在逻辑的一个题,一次性完全写对还是比较困难的 public class _Q20 {public vo ...

  9. 【完整可运行代码】剑指 Offer 29. 顺时针打印矩阵

    立志用最少的代码做最高效的表达 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2, ...

最新文章

  1. java代码代替xml实现图片
  2. Redis 4.x/5.x未授权访问漏洞
  3. eclipse没有dynamic web project_Microsoft Teams迎来Project与Roadmap功能集成
  4. Linux 技巧: 从命令行创建像素标尺
  5. so库调用java函数_linux下so动态库调用主程序函数
  6. python基础之异常处理、面向对象
  7. mysql skip-opt_FAQ系列 | mysqldump选项之skip-opt-阿里云开发者社区
  8. 进入多个页签_俄罗斯学生落地签如何办理?
  9. 高考计算机专业最低分数线是多少,2021最低多少分可以稳上二本 高考二本分数线是多少...
  10. java socket 异步回调函数_浅谈socket同步和异步、阻塞和非阻塞、I/O模型
  11. python数据结构与算法知识点_数据结构和算法基础知识点(示例代码)
  12. ajax返回的java list_ssm+ajax异步请求返回list遍历
  13. ipad pro + zotero + 坚果云 + PDF Expert 搭建多平台文献管理(自用备忘)
  14. 微信朋友圈装x代码_朋友圈生成器有哪些_微信朋友圈生成器大全_微信朋友圈装逼生成器下载_飞翔软件专题...
  15. Delphi 2007 体验
  16. lbs多城市切换php源码,多省份多城市多区县切换 专业版(dicky_multicityswitch) dz插件分享,可以随意切换到其它地区分站功能...
  17. 情情の日安的个人介绍
  18. AD域和LDAP协议
  19. 来说下华为专属分享功能——Huawei Share2.0
  20. Golang分布式应用之etcd

热门文章

  1. linux客户端交互,客户端交互性
  2. 循环冗余校验码CRC原理和实例
  3. HDCTF-2nd复盘
  4. Mac电脑Safari 浏览器中Cookie 和网站数据如何管理
  5. UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xca in position 24: invalid continuation byte
  6. mojave时间机器文件服务器,在 Mac 上可以与时间机器配合使用的磁盘类型
  7. RGB565,RGB8888等相关
  8. 小白兔写话_可爱的小白兔二年级写话
  9. ntohs和htons区别?
  10. 【C语言】字符串函数详解