題目描述
輸入一個矩陣,按照從外向里以順時針的順序依次打印出每一個數字,例如,如果輸入如下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.
分析
從外圈到內圈的順序依次打印的。
假設這個矩形的行數是rows,列數是columns。打印第一圈的左上角坐標為(0, 0),第二圈左上角的坐標為(1, 1),可以發現左上角坐標中行標和列標總是相同的。所以可以在矩形上選取左上角(start, start)的一圈為分析對象。
對於一個5x5的矩陣,最后一圈只有一個數字,對應的坐標是(2, 2)。發現5>2x2。對於一個6x6的矩陣,最后一圈有4個數字,其左上角的坐標仍然是(2, 2),發現6>2x2仍然成立,所以讓循環的條件為columns > startX * 2並且rows > startY * 2。
下來分析如何打印一圈
將打印一圈分為4步:
- 第一步,從左到右打印一行
- 第二步,從上到下打印一列
- 第三步,從右到左打印一行
- 第四步,從下到上打印一列
每一步根據起始坐標和終止坐標來用一個循環即能實現。
分析打印時每一步的前提條件:
- 第一步是必須的,因為打印一圈至少有一步。
- 如果只有一行,那么就不需要第二步了,也就是說第二步的前提條件是終止行號大於起始行號
- 需要第三步的前提條件是圈內至少有兩行兩列,也就是說除了終止行號大於起始行號,還要求終止列號大於起始列號。
- 第四步的前提條件是至少有三行兩列,因此要求終止行號比起始行號至少大2,同時終止列好=號大於起始列號。
代碼實現
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
if(matrix == null || matrix.length <= 0 || matrix[0].length <= 0) {
return null;
}
int start = 0;
int columns = matrix[0].length;
int rows = matrix.length;
ArrayList list = new ArrayList<Integer>();
while((columns > start * 2) && (rows > start * 2)) {
this.AppendListMatrix(list, matrix, columns, rows, start);
++start;
}
return list;
}
public void AppendListMatrix(ArrayList list, int[][] matrix, int columns, int rows, int start) {
int endX = columns - 1 - start;
int endY = rows - 1 - start;
for (int i = start; i <= endX; i++) {
list.add(matrix[start][i]);
}
if(start < endY) {
for (int i = start + 1; i <= endY; i++) {
list.add(matrix[i][endX]);
}
}
if(start < endX && start < endY) {
for (int i = endX - 1; i >= start ; i--) {
list.add(matrix[endY][i]);
}
}
if(start < endX && start < endY - 1) {
for (int i = endY - 1; i >= start +1; i--) {
list.add(matrix[i][start]);
}
}
}
}