一、题目

  输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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     2     3    4

             5     6     7    8

              9   10   11   12

             13  14   15   16

二、思路

问题的本质其实就是打印一个方形。每一个方形代表矩阵的每一层。
但是,打印一个方形,我们必须要知道它的两个对角顶点的位置。有了对角顶点的位置,打印一个方形并不困难了。
注意:对于一个矩阵,它的长宽可能会不一样,所以,我们需要判断处理。
两个对角顶点的位置分别为左上角和右下角我们假设矩阵行数是rows,列数是culmns。
则左上角的位置行标和列标总是相同的,我们取左上角为(start,atart),则右下角为(rows-1,clumns-1)。
问题的关键在于,怎么确定循环终止条件:
对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.

三、代码

形式1:顺时针遍历 的矩阵存入ArrayList

import java.util.ArrayList;

public class PrintMatrix {

    ArrayList<Integer> arrayList = new ArrayList<Integer>(); //存储顺时针打印的矩阵

    //循环打印矩阵
public ArrayList<Integer> printMatrix(int[][] matrix) {
int clumns = matrix[0].length;//矩阵的列数
int rows = matrix.length;//矩阵的行数
if (matrix == null)//如果为空,返回null
return null; int start = 0;//定义矩阵初始元数的序号 while (clumns > 2 * start && rows > 2 * start) { //对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.
printMatrixInCircle(matrix, clumns, rows, start);//调用打印一圈的方法
start++;
}
return arrayList;
} //打印一圈
private void printMatrixInCircle(int[][] matrix, int clumns, int rows, int start) {
int endX = clumns - 1 - start;
int endY = rows - 1 - start;
for (int i = start; i <= endX; ++i) {
int n = matrix[start][i];
arrayList.add(n);
}
//从上到下打印一列
if (start < endY) {
for (int j = start + 1; j <= endY; ++j) {
int n = matrix[j][endX];
arrayList.add(n);
}
}
System.out.println();
//从右到左打印一行
if (start < endY && start < endX) {
for (int k = endX - 1; k >= start; k--) {
int n = matrix[endY][k];
arrayList.add(n);
}
}
//从下到上打印一列
if (start < endX && start < endY - 1) {
for (int l = endY - 1; l > start; l--) {
int n = matrix[l][start];
arrayList.add(n);
}
}
}
}

形式2:直接顺时针打印矩阵

public class PrintMatrix {
public static void main(String[] args) {
int[][] num = new int[][]{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, {16, 17, 18, 19, 20}, {21, 22, 23, 24, 25}};
System.out.println("顺时针打印5x5的矩阵");
printMatrixClockwisely(num, 5, 5);
int[][] num2 = new int[][]{{1, 2, 3, 4, 5}};
System.out.println("顺时针打印1x5的矩阵");
printMatrixClockwisely(num2, 5, 1);
int[][] num3 = new int[][]{{1}, {2}, {3}, {4}, {5}};
System.out.println("顺时针打印5x1的矩阵");
printMatrixClockwisely(num3, 1, 5);
} //循环打印矩阵
public static void printMatrixClockwisely(int[][] numbers, int clumns, int rows) {
if (numbers == null || clumns <= 0 || rows <= 0)
return;
int start = 0;
//对一个5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2*2.对于一个6*6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2*2依然成立。于是我们可以得出继续循环的条件是columns>2*start并且rows>2*start.
while (clumns > 2 * start && rows > 2 * start) {
printMatrixInCircle(numbers, clumns, rows, start);
start++;
}
} //打印一圈
private static void printMatrixInCircle(int[][] numbers, int clumns, int rows, int start) {
int endX = clumns - 1 - start;
int endY = rows - 1 - start;
//从左到右打印一行
for (int i = start; i <= endX; ++i) {
int n = numbers[start][i];
System.out.print(n + " ");
}
System.out.println();
//从上到下打印一列
if (start < endY) {
for (int j = start + 1; j <= endY; ++j) {
int n = numbers[j][endX];
System.out.print(n + " ");
}
}
System.out.println();
//从右到左打印一行
if (start < endY && start < endX) {
for (int k = endX - 1; k >= start; k--) {
int n = numbers[endY][k];
System.out.print(n + " ");
}
}
System.out.println();
//从下到上打印一列
if (start < endX && start < endY - 1) {
for (int l = endY - 1; l > start; l--) {
int n = numbers[l][start];
System.out.print(n + " ");
}
}
System.out.println();
}
}

-------------------------------------------------------------------------------------------------------

参考链接:

1、https://www.nowcoder.com/questionTerminal/9b4c81a02cd34f76be2659fa0d54342a

2、http://blog.163.com/wzz_vie/blog/static/25164906720173106320185/

剑指offer十九之顺时针打印矩阵的更多相关文章

  1. 剑指Offer:面试题20——顺时针打印矩阵(java实现)

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

  2. 剑指 offer面试题20 顺时针打印矩阵

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

  3. 剑指offer(19)顺时针打印矩阵

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

  4. 【剑指Offer】19、顺时针打印矩阵

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

  5. 【剑指offer】题目20 顺时针打印矩阵

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

  6. 牛客网剑指offer第19题——顺时针打印矩阵

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

  7. 剑指Offer(十九)——顺时针打印矩阵

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

  8. 《剑指offer》从尾到头打印链表

    本题来自<剑指offer> 从尾到头打印链表 题目: 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 思路: 方案一:首先遍历到尾部,然后从尾部进行到头值进行操作,后进先 ...

  9. 菜鸟刷题路:剑指 Offer 06. 从尾到头打印链表

    剑指 Offer 06. 从尾到头打印链表 class Solution { public int[] reversePrint(ListNode head) { Stack<Integer&g ...

随机推荐

  1. windows socket扩展函数

    1.AcceptEx() AcceptEx()用于异步接收连接,可以取得客户程序发送的第一块数据. BOOL AcceptEx( _In_  SOCKET       sListenSocket,   ...

  2. EXCEL中R1C1样式引用

    主要引用http://club.excelhome.net/thread-759847-1-1.html Sub chengji() ' ' 宏1 宏 ' Dim Finalrow As Intege ...

  3. es5数组的新方法

    1.every方法 //逻辑判断返回值为一个Boolean值 every方法就是每一个返回函数的返回值都是true的时候,才为true,否则为false var arr=[1,2,5,88,5,555 ...

  4. VESA时序与BT1120的区别

    在实现内嵌传输的过程中,笔者参考VESA的时序,也就是下图,实现了一个内嵌同步的程序,同步码放在H Back Porch与H Front Porch的后端与前端,但是在传输过程中发现接收端画面不正常. ...

  5. VB网络编程中Winsock的使用

    原文链接:http://tech.163.com/06/0407/14/2E46BB930009159S.html 如同上面的内容所描述的,不论您使用UDP协议或是TCP协议,Winsock控件都可以 ...

  6. UML(一)下载与安装

    三步 Step1 下载绿色版: http://www.pc6.com/softview/SoftView_64080.html Step2 下载汉化包,(提供一个地址): http://downloa ...

  7. 1.2.2实现Runnable接口

    使用Runnable创建线程 package com.cky.runner; /** * Created by chenkaiyang on 2017/12/2. */ public class My ...

  8. Update Node.js Package.json

    Update the latest package while using node.js, follow the command as following. npm i -g npm-check-u ...

  9. Java理论学时第五节。课后作业。

    随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中. 设计思路:先声明一个数组,再利用for循环对每一个元素赋随机生成的值,在求所有数的和,再根据要 ...

  10. HDU3488 Tour

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submi ...