🔥题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
输入:matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
输出:[1, 2, 3, 6, 9, 8, 7, 4, 5]
☘️解析
这道题目的核心难点有两个:
1)如何顺时针打印?
2)何时终止打印?
1)如何顺时针打印?
收缩法。设置四个指针分别指向四个边界:top、bottom、left、right;每次打印完一行/一列后,收缩其中一个指针即可。
2)何时终止打印?
终止打印的情况也是有4个:打印完一行(从左到右、从右到左),打印完一列(从上到下,从下到上)。
四种打印方向结束后正好对应这四种终止情况——每次收缩指针后,判断其是否合法即可(top > bottom
、left > right
为不合法)。
left right
top a a a a a
d e e e b
d h i f b
d g g f b
bottom c c c c b
🧊代码
class Solution {
public int[] spiralOrder(int[][] matrix) {
if (matrix.length == 0) {
return new int[0];
}
int top = 0;
int bottom = matrix.length - 1;
int left = 0;
int right = matrix[0].length - 1;
int[] res = new int[(bottom + 1) * (right + 1)];
int index = 0;
while (true) {
for (int i = left; i <= right; i++) res[index++] = matrix[top][i];
if (++top > bottom) break;
for (int i = top; i <= bottom; i++) res[index++] = matrix[i][right];
if (--right < left) break;
for (int i = right; i >= left; i--) res[index++] = matrix[bottom][i];
if (--bottom < top) break;
for (int i = bottom; i >= top; i--) res[index++] = matrix[i][left];
if (++left > right) break;
}
return res;
}
}
🌸补充
第一个关键点(收缩)其实不难想到,标清楚边界指针即可。
第二个关键点(终止)很容易绕晕,但只要弄清楚4种打印方向结束后正好对应4种终止情况,问题即可迎刃而解。