点击查看剑指Offer全解【Java & Golang】实现
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
思路
这道题应该是剑指Offer中最复杂的一个问题了,因为它难在思考过程简单,但是实现起来需要判断的边界条件多,这里给剑指Offer的讲解:
把打印一圈分为四步:第一步从左到右打印一行,第二步从上到下打印一列,第三步从右到左打印一行,第四步从下到上打印一列。每一步我们根据起始坐标和终止坐标用一个循环就能打印出一行或者一列。
不过值得注意的是,最后一圈有可能退化成只有一行、只有一列,甚至只有一个数字,因此打印这样的一圈就不再需要四步。图中是几个退化的例子, 打印一圈分别只需要三步、两步甚至只有一步。
Java实现
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int[][] matrix) {
ArrayList<Integer> res = new ArrayList<>();
if (matrix.length == 0) {
return res;
}
int row = matrix.length;
int col = matrix[0].length;
// 上下左右
int top = 0, bottom = row - 1, left = 0, right = col - 1;
while (top <= bottom && left <= right) {
// 从左到右打印
for (int i = left; i <= right; i++) {
res.add(matrix[top][i]);
}
// 从上到下打印
for (int i = top + 1; i <= bottom; i++) {
res.add(matrix[i][right]);
}
// 从右到左打印
// 防止只有一行的情况
if (top != bottom) {
for (int i = right - 1; i >= left; i--) {
res.add(matrix[bottom][i]);
}
}
// 从下到上打印
// 防止只有一列的情况
if (left != right) {
for (int i = bottom - 1; i >= top + 1; i--) {
res.add(matrix[i][left]);
}
}
// 下一圈
top++;bottom--;left++;right--;
}
return res;
}
}