题目描述:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,

例如,如果输入如下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.

测试用例:

矩阵中有多行多列、矩阵中只有一行或者一列、数组中只有一列、数组中只有一行一列。(并没有考虑矩阵为空的情况)

解题思路:

1)^-^- 规律:每次圈的起始点都是(0,0)(1,1)(start,start)行列的数字相等

^-^- 一个矩阵能划分为多少个圈:找规律

对于一个5*5的矩阵,最后一圈只有一个数字,对应的坐标为(2,2)。5>2*2

对于一个6*6的矩阵,最后一圈只有一个数字,对应的坐标为(2,2)。6>2*2

于是可以得出。让循环继续的条件是 columns>startX*2 并且 rows>startY*2

^-^- 可以把打印一圈分为四步:第一步,从左到右打印一行;第二步,从上到下打印一列;第三步,从右到左打印一行;第四步,从下到上打印一列。每一步根据起始坐标和终止坐标用循环打印出一行或者一列。

class Solution {
public:vector<int> printMatrix(vector<vector<int> > matrix) {if(matrix.size()==0)  //return result;int start = 0; //标志着第几圈int rows = matrix.size();int cols = matrix[0].size();while(rows>start*2 && cols>start*2){printMatrixInCircle( matrix,rows,cols,start);start++;}return result;}void printMatrixInCircle(vector<vector<int> > matrix,int rows,int cols,int start){int endCol = cols-1-start;int endRow = rows-1-start;//第一步:打印第一行(一定会打印)for(int col=start; col<=endCol; col++){result.push_back(matrix[start][col]);}//第二步:若行数大于等于二(即多于一行时),则会打印。即endRow-start>0if(endRow-start>0){for(int row=start+1; row<=endRow; row++)result.push_back(matrix[row][endCol]);}//第三步:至少两行两列if(endRow-start>0 && endCol-start>0){ //for(int col=endCol-1; col>=start; col--)result.push_back(matrix[endRow][col]);}//第三步:至少三行两列if(endRow-start>1 && endCol-start>0){for(int row=endRow-1; row>start; row--)result.push_back(matrix[row][start]);}}
private:vector<int> result;
};

2)int circle=((row<collor?row:collor)-1)/2+1;//圈数

3)定义四个关键变量,表示左上和右下的打印范围,限定一个圈。每次循环后缩小一圈

/*思想,用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。提交代码时,主要的问题出在没有控制好后两个for循环,需要加入条件判断,防止出现单行或者单列的情况。*/
class Solution {
public:vector<int> printMatrix(vector<vector<int> > matrix) {int row = matrix.size();int col = matrix[0].size();vector<int> res;// 输入的二维数组非法,返回空的数组if (row == 0 || col == 0)  return res;// 定义四个关键变量,表示左上和右下的打印范围int left = 0, top = 0, right = col - 1, bottom = row - 1;while (left <= right && top <= bottom) //至少有一个元素时{// left to right 一定会打印for (int i = left; i <= right; ++i)  res.push_back(matrix[top][i]);// top to bottom 行数多于1行才会打印  here 只有一行时不会进入for循环,因此该处无需判断for (int i = top + 1; i <= bottom; ++i)  res.push_back(matrix[i][right]);// right to left //至少两行两列时,才会打印 top != bottom限制至少两行 for循环限制right-1>=left,即至少两行if (top != bottom)for (int i = right - 1; i >= left; --i)  res.push_back(matrix[bottom][i]);// bottom to top //至少三行两列  left != right限制两列 bottom - 1> top 至少三列if (left != right)for (int i = bottom - 1; i > top; --i)  res.push_back(matrix[i][left]);left++,top++,right--,bottom--; //缩小一圈}return res;}
};

4)顺着走,即向右->向下->向左->向上,一共要走(长*宽)步。遇到边界就改变方向,当向上碰到顶的时候,四个边界都缩小。思路简单,一个循环即可!

class Solution {
public:vector<int> printMatrix(vector<vector<int> > matrix) {vector<int> ret;if(matrix.empty())return ret;int x,y,cnt=matrix[0].size()*matrix.size(); //一共需要打印的个数//右rEdge 下dEdge 左lEdge 上uEdgeint rEdge=matrix[0].size()-1,dEdge=matrix.size()-1,lEdge=0,uEdge=0;//bool first=true;for(x=0,y=0;cnt>0;cnt--){ //从(0,0)开始ret.push_back(matrix[x][y]);//go  rightif(x==uEdge){  //上边界if(y<rEdge) //小于右边界时,向右移动。y++y++;else if(y==rEdge) //到达右边界,向下移动x++;continue; //不会再判断后面的if了}//downif(y==rEdge){if(x<dEdge)x++;else if(x==dEdge){y--;}continue; //不会再判断后面的if了}//leftif(x==dEdge){if(y>lEdge)y--;else if(y==lEdge){x--;}continue; //不会再判断后面的if了}//upif(y==lEdge){if(x>uEdge+1)x--;else if( x==uEdge+1){ //到达一圈的最后一个点y++;lEdge++;uEdge++;rEdge--;dEdge--;}continue;}//;3}return ret;}
};

  

  

  

转载于:https://www.cnblogs.com/GuoXinxin/p/10449568.html

29 顺时针打印矩阵(四-画图让抽象问题形象化)相关推荐

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

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

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

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

  3. 29.顺时针打印矩阵

    首先顺时针打印矩阵,需要通过图解来理解: 上面是一个3 * 3 的矩阵,我们要将其按照顺时针打印,那么打印的结果就是 1 ➡ 2 ➡ 3 ➡ 4 ➡ 5 ➡ 6 ➡ 7 ➡ 8 ➡ 9 我们可以通过模 ...

  4. 剑指offer:面试题29. 顺时针打印矩阵

    题目:顺时针打印矩阵 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9 ...

  5. 剑指 Offer 29. 顺时针打印矩阵

    题目 剑指offer的解题思路 顺时针打印矩阵,可以分解为每次打印一个数,顺序是从左到右,从上到下,然后从右到左,从下到上. 打印每一圈的起点(startX,startY)分别为(0,0),(1,1) ...

  6. 剑指offer——29.顺时针打印矩阵(不熟)

    题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字 ...

  7. 打印矩阵 java_【Java】 剑指offer(29) 顺时针打印矩阵

    本文参考自<剑指offer>一书,代码采用Java语言. 题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 思路 每次打印矩阵最外面的一圈(用方法printMatrix ...

  8. leetcode —— 面试题29. 顺时针打印矩阵

    输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] - ...

  9. 【leetcode】剑指 Offer 29. 顺时针打印矩阵(shun-shi-zhen-da-yin-ju-zhen-lcof)(模拟)[简单]

    链接 https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/ 耗时 解题:38 min 题解:10 min 题意 输入一 ...

  10. 剑指offer 29 顺时针打印矩阵(可逆时针,任一点开始)

    原书上写的解太麻烦了,而且还没有扩展性(比如从右上角开始打印,或者逆时针打印). 此外多个for循环的起止点也让人头晕,每个方向都要单独判断步进方向,因此代码也缺少优雅性. 这里我用direction ...

最新文章

  1. 1.2 Spyder的基本使用
  2. uiautomator环境搭建所遇问题汇总
  3. redis cluster配置文件和集群状态详解
  4. Linux C : GDB调试命令汇总
  5. js中match的用法
  6. 爬虫项目——xpath练手(1)
  7. 操作系统学习笔记 002 安装NASM
  8. 不同加密算法的国际标准与国标
  9. 算法:把排好序的链表转换为二叉排序树Convert Sorted List to Binary Search Tree
  10. SpringSecurity下做POST测试以及传递实体
  11. 华为c8818刷原生Android 6,华为C8818刷机教程_华为C8818强刷官方rom系统包
  12. 各类任务的数据集大数据库
  13. 透过现象看本质(一)
  14. https安全证书过期失效的原因以及解决方法
  15. 手机有软件测试网络通不通,怎样使用ping命令测试网络通不通
  16. JavaScript-05
  17. NAS网络存储中使用Docker安装百度网盘客户端教程
  18. pdfjs 字体新增_自定义字体在jsPDF中?
  19. form编译报错:ORA-12162: TNS:net service name is incorrectly specified解决办法
  20. 微信分享接口SDK(前端js和后端php)

热门文章

  1. java 文件去除扩展名_使用Java删除所有带扩展名的文件
  2. c 子类对象 访问父类对象受保护成员_看了这个,你就会搞对象了
  3. AcWing 788. 逆序对的数量
  4. java 验证服务器宕机_java服务宕机原因查询
  5. 什么是java socket_java 网络编程,Socket编程
  6. Linux的/var/www/html目录
  7. 【Android】ArcFaceDemo
  8. linux系统管理常用命令--top
  9. babel-preset-env
  10. [操作系统] 线程和进程的简单解释