题目描述

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

  则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。

牛客网刷题地址

思路分析

将矩阵看成若干个顺时针方向的圈组成.

  1. 第一步:接下来分析循环结束的条件。假设这个矩阵的行数是rows,列数是columns。打印第-圈的左上角的坐标是(0, 0),第二圈的左上角的坐标是(1, 1),以此类推。我们注意到,左上角的坐标中行标和列标总是相同的,于是可以在矩阵中选取左上角为(start, start)的一圈作 为我们分析的目标。对于一个5X5的矩阵而言,最后一-圈只有一个数字,对应的坐标为(2, 2)。我们发现5> 2x2。对于一个6X6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2, 2)。 我们发现6>2*2依然成立。于是可以得出,让循环继续的条件是columns > startXx2并且rows > startY*2。
  2. 第二步:如何打印一圈的矩阵:
    我们可以分为四步:从左到右,从上到下,从右到左,从下到上,但是打印一圈时会出现如下特殊情况:所以说,这四步并不是都要执行

可以将其想象为一个原点在左上角的(X,Y)坐标轴,来进行分析。

测试用例

  1. 数组中有多行多列;数组中只有一行;数组中只有一列;数组中只一行一列。

Java代码

public class Offer29 {
public static void main(String[] args) {
test1();
test2();
test3();
} public static ArrayList<Integer> printMatrix(int[][] matrix) {
return Solution1(matrix);
} private static ArrayList<Integer> Solution1(int[][] matrix) {
if (matrix == null || matrix.length <= 0 || matrix[0].length <= 0) {
return null;
}
int start = 0;
int rows = matrix.length;
int columns = matrix[0].length; ArrayList<Integer> listSum = new ArrayList<Integer>(); while (columns > start * 2 && rows > start * 2) {
ArrayList<Integer> list = printMatrix(matrix, rows, columns, start);
listSum.addAll(list);
++start;
} return listSum;
} public static ArrayList<Integer> printMatrix(int[][] matrix, int rows, int columns, int start) {
int endX = columns - 1 - start;// 横坐标
int endY = rows - 1 - start;// 竖坐标
ArrayList<Integer> list = new ArrayList<Integer>();
// 左到右打印
for (int i = start; i <= endX; i++) {
int num = matrix[start][i];
System.out.println(num + ",");
list.add(num);
} // 从上到下打印
if (start < endY) {
for (int j = start + 1; j <= endY; j++) {
int num = matrix[j][endX];
System.out.println(num + ",");
list.add(num);
}
} // 从右到左打印
if (start < endX && start < endY) {
for (int i = endX - 1; i >= start; i--) {
int num = matrix[endY][i];
System.out.println(num);
list.add(num);
}
}
// 从下往上打印
if (start < endX && start + 1 < endY) {
for (int j = endY - 1; j >= start + 1; j--) {
int num = matrix[j][start];
System.out.print(num + ",");
list.add(num);
}
} return list; } private static void test1() {}
private static void test2() {}
private static void test3() {} }

代码链接

剑指Offer代码-Java

最新文章

  1. MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句
  2. ios语音识别
  3. Awesome
  4. Swift学习之熟悉控件
  5. Microsoft Azure Web Sites应用与实践【1】—— 打造你的第一个Microsoft Azure Website
  6. Win7搭建nginx+php+mysql开发环境以及websocket聊天实例测试
  7. URL参数GB2312和UTF-8编码 自动识别
  8. MongoDB中的连接池
  9. ASP.NET WebAPI 03 返回结果
  10. Dijkstra 算法、Kruskal 算法、Prim算法、floyd算法
  11. 无线端通用的reset样式
  12. spring 自定义schema
  13. C++11 virtual函数学习笔记
  14. Lyx输入中文与代码高亮
  15. 【学生成绩管理系统】 大二c语言作业
  16. H5新特性之data-*
  17. eval() 和 int()区别,以及eval作用
  18. Ubuntu18.04安装Guake下拉式终端
  19. MongoDB的数据类型介绍
  20. mac chrome 浏览器开启允许跨域

热门文章

  1. zxing 扫码第三方SDK版本不兼容问题
  2. React 如何搭建脚手架
  3. kafka同步异步消费和消息的偏移量(四)
  4. 对于微信UnionID在公众平台以及小程序里面的获取
  5. 码农&quot;混子&quot;的思想转变
  6. GitPage部署
  7. C#之BackgroundWorker从简单入门到深入精通的用法总结
  8. 后端开发之chrome开发者模式
  9. Vue cli2.0 项目中使用Monaco Editor编辑器
  10. 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧