2020.05.06
题目
输入一个矩阵,按照从外向里以顺时针的顺序依次扫印出每一个数字。
点击链接
解题思路
把打印一圈分为四步:第一步从左到右打印一行,第二步从上到下打印一列,第三步从右到左打印一行,第四步从下到上打印一列。每一步我们根据起始坐标和终止坐标用一个循环就能打印出一行或者一列。
但是,我们会遇到一些情况,就是随着一圈又一圈的读,最后退化到 图4.4 的情况 , 打印一圈分别只需要三步、两步甚至只有一步。
因此我们要仔细分析打印时每一步的前提条件:
1、第一步总是需要的, 因为打印一圈至少有一步。
2、第二步的前提条件:是终止行号大于起始行号(原因:如果只有一行,那么就不用第二步了)。
3、第三步的前提条件:是圈内至少有两行两列,也就是说除了要求终止行号大于起始行号之外,同时终止列号大于起始列号。
4、同理第三步,第四步的前提条件:是至少有三行两列,因此除了要求终止行号比起始行号至少大2,同时终止列号大于起始列号。
package offer20;
public class Test {
public static void printCycle(int[][] numberArray) {
if(numberArray == null || numberArray.length == 0) {
System.out.println("入参不合法");
return;
}
//初始化行的起点
int x = 0;
//初始化列的起点
int y = 0;
//行起点值不大于(numberArray.length-1)/2
//列起点值不大于(numberArray[0].length-1)/2
while (x <= (numberArray.length-1)/2 && y <= (numberArray[0].length-1)/2) {
print(numberArray,x,y);
x++;
y++;
}
}
public static void print(int[][] numberArray,int x,int y) {
int rows = numberArray.length - 1;
int cols = numberArray[0].length - 1;
for(int i = y;i <= cols - y;i++ ) {
System.out.print(numberArray[x][i] + " ");
}
//注意我们要排除第一行最后一个打印过的
//总行数 - 起始行数 > 起始行数;总行数 - 起始行数 表示最后面的行下标;下面同理;
if(rows - x > x) {
for(int i = x + 1 ;i <= rows - x;i++ ) {
System.out.print(numberArray[i][cols - y] + " ");
}
}
if( rows - x > x && cols - y > y ) {
for(int i = cols-y-1;i >= x; i--) {
System.out.print(numberArray[rows - x][i] + " ");
}
}
if( rows - x > x && cols - y > y + 1 ) {
//防止打印这一圈第一个值
for(int i = rows-x-1;i > x;i-- ) {
System.out.print(numberArray[i][y] + " ");
}
}
}
public static void main(String[] args) {
int[][] numbers1 = {
{1, 2, 3, 4, 5},
{16, 17, 18, 19, 6},
{15, 24, 25, 20, 7},
{14, 23, 22, 21, 8},
{13, 12, 11, 10, 9},
};
printCycle(numbers1);
System.out.println();
int[][] numbers2 = {
{1, 2, 3, 4, 5, 6, 7, 8},
{22, 23, 24, 25, 26, 27, 28, 9},
{21, 36, 37, 38, 39, 40, 29, 10},
{20, 35, 34, 33, 32, 31, 30, 11},
{19, 18, 17, 16, 15, 14, 13, 12},
};
printCycle(numbers2);
System.out.println();
int[][] numbers3 = {
{1, 2, 3, 4, 5, 6, 7, 8}
};
printCycle(numbers3);
System.out.println();
int[][] numbers4 = {
{1, 2, 3, 4, 5, 6, 7, 8},
{16, 15, 14, 13, 12, 11, 10, 9}
};
printCycle(numbers4);
System.out.println();
int[][] numbers5 = {
{1},
{2},
{3},
{4},
{5},
{6},
{7},
{8}
};
printCycle(numbers5);
System.out.println();
int[][] numbers6 = {
{0, 1},
{15, 2},
{14, 3},
{13, 4},
{12, 5},
{11, 6},
{10, 7},
{9, 8}
};
printCycle(numbers6);
System.out.println();
int[][] numbers7 = {
{1, 2},
{4, 3}
};
printCycle(numbers7);
System.out.println();
int[][] numbers8 = {
{1}
};
printCycle(numbers8);
System.out.println();
// 0个元素的数组
printCycle(new int[][]{{}});
// 空数组
printCycle(null);
}
}
我写的时候也错了好几次,行遍历时要想列变化,列遍历要想着行变化,注意边界且四个部分不要重复读值,希望对正在阅读这篇文章的你有所帮助。