题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下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.
示例代码
public ArrayList<Integer> printMatrix(int [][] matrix) {
if (matrix == null || matrix.length == 0) {
return null;
}
ArrayList<Integer> list = new ArrayList<>();
int startX = 0;
int startY = 0;
int rows = matrix.length;
int cols = matrix[0].length;
while (rows > startX*2 && cols > startY*2) {
int endX = rows - startX - 1;
int endY = cols - startY - 1;
// 从左往右打印 ,无条件执行
for (int j = startY; j <= endY; j++) {
list.add(matrix[startX][j]);
}
// 从上往下打印 ,所在圈必须有两行、一列以上
if (startX < endX) {
for (int i = startX + 1; i <= endX; i++) {
list.add(matrix[i][endY]);
}
}
// 从右到左打印 ,所在圈必须有两行、两列以上
if (startX < endX && startY < endY) {
for (int j = endY - 1; j >= startY; j--) {
list.add(matrix[endX][j]);
}
}
// 从下到上打印,所在圈必须由三行、两列以上
if (startX < endX - 1 && startY < endY) {
for (int i = endX - 1; i >= startX + 1; i--) {
list.add(matrix[i][startY]);
}
}
startX ++;startY ++;
}
return list;
}
要点解析
结合图看下边的判断条件,一定要注意XY轴
- 循环结束条件判断
- rows > startX2 && cols > startY2,多画几个图就发现了(如5X5的,5x1的,2x3的)
- 顺指针循环打印一圈
- 从左到右:
- (0, 0)->(0, 1)->(0, 2)->(0, 3)
- matrix[startX][j](j从0(startY)增至 3(endY))
- 从上到下:
- (1, 3)->(2, 3)->(3, 3)
- matrix[i][endY](i从1(startX+1)增至 3(endX))
- 从右到左:
- (3, 2)->(3, 1)->(3, 0)
- matrix[endX][j](j从2(endY-1)减至 0(startY))
- 从下到上:
- (2, 0)->(1, 0)
- matrix[i][start](i从2(endX-1)减至 1(startX+1))
- 从左到右:
- 边界判断
- 从左到右: 这一步一定会有,无条件执行
- 从上到下: 所在圈必须有两行、一列以上,endX>startX
- 从右到左: 所在圈必须有两行、两列以上,endX>startX && endY>startY
- 从下到上: 所在圈必须由三行、两列以上,endX-1>startX && endY>startY
边界图形就不画了,纸上画的有点乱,自己画的时候多往极端上想,牛客的测试用例都点丰富啊
总结
这道题测试好多次,总有边界条件没有想到,后来看了看别人的做法,豁然开朗。总的来说这道题还是不错的,锻炼人的思维完整性。
附上大佬文章链接(https://blog.youkuaiyun.com/yiyiwudian/article/details/46707875)