题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.
分析:
Q1:如何根据输入来知道矩阵的长和宽呢?
A1:想了半天,发现自己果然很傻,看看题目给出的初始代码:
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
}
}
显然,输入的参数是一个二维数组,那么长宽就很显然了。
画图思考如下:
顺时针打印
最直接的想法就是按照一圈是一个for循环来写就可以了。
最主要的问题是要考虑边界值,例如上图,4既在第一圈的上边也在第一圈的右边,我们输出时,要求只输出一个4即可。
例如,当输入的矩形不是正方形,要考虑到其他特殊情况的判断:
{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
{{1},{2},{3}},长或宽有一项长度为1时,直接遍历输出即可。
{1,2},{3,4},{5,6},{7,8},{9,10},这种情况下,length远比width大,外层根据length来判断的for循环可以进行下去,但是内层已经没有可以访问的元素了,这时候需要根据width进行判断。
其实好多这些特殊情况在第一次写的时候都没哟考虑到,在本地运行并测试不同的测试样例的时候,就发现了这些情况,然后在原本代码的基础上进行修改和调整。
希望以后能考虑的更加全面,而不是在出现问题后再进行调整。
代码:
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
int length = matrix.length; //行长度:矩阵的长
int width = matrix[0].length; //列长度:矩阵的宽
ArrayList<Integer> arrayList = new ArrayList<Integer>();
if(matrix == null || length==0 || width==0) return null;
if(length==1){
for(int a1 = 0;a1<width;a1++){
arrayList.add(matrix[0][a1]);
}
return arrayList;
}
if(width==1){
for(int a2 = 0;a2<length;a2++){
arrayList.add(matrix[a2][0]);
}
return arrayList;
}
//一次循环是一圈
for(int i =0;i<length-i;i++){
int j=i;
if(j<width-i) {
//一圈的上边
for (;j<width - i; j++) {
arrayList.add(matrix[i][j]);
}
//一圈的右边
for (int k = i + 1; k < length - i; k++) {
arrayList.add(matrix[k][width - 1 - i]);
}
int f = length - 1 - i; //下边所在的行数
if (f != i) {
//一圈的下边
for (int m = width - 1 - i - 1; m >= i; m--) {
arrayList.add(matrix[f][m]);
}
//一圈的左边
for (int n = f - 1; n > i; n--) {
arrayList.add(matrix[n][i]);
}
}
}
}
return arrayList;
}
}
运行结果:
运行通过
后记:
这里再附上本地调试运行的代码,仅供参考:
package xiazhen;
import java.util.ArrayList;
/**
* @Author : 夏臻
*
* @Description: 打印矩阵
*
* @Date: 10:05 2018/5/29
**/
public class printMatrix {
public static void main(String[] args){
int[][] inMatrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
ArrayList<Integer> out = printMatrix(inMatrix);
System.out.println("希望的结果是:"+"1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.");
System.out.println(out);
int[][] inMatrix2 = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
ArrayList<Integer> out2 = printMatrix(inMatrix2);
System.out.println("希望的结果是:"+"1,2,3,4,8,12,11,10,9,5,6,7.");
System.out.println(out2);
int[][] inMatrix3 = {{1},{2},{3}};
ArrayList<Integer> out3 = printMatrix(inMatrix3);
System.out.println("希望的结果是:"+"1,2,3");
System.out.println(out3);
int[][] inMatrix4 = {{1,2},{3,4},{5,6},{7,8},{9,10}};
ArrayList<Integer> out4 = printMatrix(inMatrix4);
System.out.println("希望的结果是:"+"[1,2,4,6,8,10,9,7,5,3]");
System.out.println(out4);
}
public static ArrayList<Integer> printMatrix(int[][] matrix){
int length = matrix.length; //行长度:矩阵的长
int width = matrix[0].length; //列长度:矩阵的宽
ArrayList<Integer> arrayList = new ArrayList<Integer>();
if(matrix == null || length==0 || width==0) return null;
if(length==1){
for(int a1 = 0;a1<width;a1++){
arrayList.add(matrix[0][a1]);
}
return arrayList;
}
if(width==1){
for(int a2 = 0;a2<length;a2++){
arrayList.add(matrix[a2][0]);
}
return arrayList;
}
//一次循环是一圈
for(int i =0;i<length-i;i++){
int j=i;
if(j<width-i) {
//一圈的上边
for (;j<width - i; j++) {
arrayList.add(matrix[i][j]);
}
//一圈的右边
for (int k = i + 1; k < length - i; k++) {
arrayList.add(matrix[k][width - 1 - i]);
}
int f = length - 1 - i; //下边所在的行数
if (f != i) {
//一圈的下边
for (int m = width - 1 - i - 1; m >= i; m--) {
arrayList.add(matrix[f][m]);
}
//一圈的左边
for (int n = f - 1; n > i; n--) {
arrayList.add(matrix[n][i]);
}
}
}
}
return arrayList;
}
}
主要就是各种复杂情况的综合全面考虑,对于for循环输出一圈的数字其实很简单,只要把握到一个关键点:每一圈的初始元素都是矩阵第i行的第i列的元素,相应地对应二维数组中第i组第i位的元素,把握好了每一圈初始元素的位置,按照顺时针“上,右,下,左”来循环遍历就可以了,注意把握两条边相邻的位置。
网友评论