题意给得很明确,要我们按顺时针遍历输出整个矩阵的元素,那我们就顺着题意,看一下遍历过程中会需要用到哪些边界条件。
可以看到,从左到右遍历时,我们需要知道开始的位置(左边界),以及结束的位置(右边界),同理,从上往下遍历时,我们也需要知道开始的位置(上边界)以及结束位置(下边界)。这样一来就很明确了,我们需要维护上、下、左、右四个边界,用以约束螺旋遍历时的边界,后面的逻辑就很简单了:
- 第一步先从左上角往右边界遍历,直到走到右边界,之后把上边界往下挪
- 第二步从右上角往下边界遍历,直到走到下边界,之后把右边界往左挪
- 第三步从右下角往左边界遍历,直到走到左边界,之后把下边界往上挪
- 第四步从左下角往上边界遍历,直到走到上边界,之后把左边界往下挪
这样,我们就完成了整个矩阵的遍历,代码如下:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
int upperBound = 0, lowerBound = m - 1;
int leftBoud = 0, rightBound = n - 1;
List<Integer> res = new ArrayList<>();
while (res.size() < m * n) {
// 1、左边界右移
if (upperBound <= lowerBound) {
for (int i = leftBoud; i <= rightBound; i++) {
res.add(matrix[upperBound][i]);
}
upperBound++;// 上边界往下挪动
}
// 2、上边界下移
if (leftBoud <= rightBound) {
for (int i = upperBound; i <= lowerBound; i++) {
res.add(matrix[i][rightBound]);
}
rightBound--;// 右边界往左挪动
}
// 3、右边界左移
if (upperBound <= lowerBound) {
for (int i = rightBound; i >= leftBoud; i--) {
res.add(matrix[lowerBound][i]);
}
lowerBound--;// 下边界往上挪动
}
// 4、下边界上移动
if (leftBoud <= rightBound) {
for (int i = lowerBound; i >= upperBound; i--) {
res.add(matrix[i][leftBoud]);
}
leftBoud++;// 左边界往右挪动
}
}
return res;
}
}