循环打印二维数组/矩阵的规律:
从左向右打印,此时上边界向下移动,行不变,列++
从上向下打印,此时右界向左移动,列不变,行++
从右向左打印,此时下边界向上移动,行不变,列--
从下向上打印,此时上左界向右移动,列不变,行--
算法框架
int t=0,b=m-1,l=0,r=n-1;
while(true){
//从左向右打印,此时上边界向下移动,行不变,列++
for(int i=l;i<=r;i++){
num[top][i];
}
t++;
if(t>b) break;
//从上向下打印,此时右界向左移动,列不变,行++
for(int i=t;i<=b;i++){
num[i][r];
}
r--;
if(l>r) break;
//从右向左打印,此时下边界向上移动,行不变,列--
for(int i=r;i>=l;i-){
num[b][i];
}
b--;
if(t>b) break;
//从下向上打印,此时上左界向右移动,列不变,行--
for(int i=b;i>=t;i--){
num[i][l];
}
l++;
if(l>r) break;
}
实现
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0){
return new int[]{};
}
List<Integer> list = new ArrayList<>();
int top = 0;
int bottom = matrix.length-1;
int left = 0;
int right = matrix[0].length-1;
while(true) {
//从左向右打
for(int i=left;i<=right;i++) {
list.add(matrix[top][i]);
}
if(++top>bottom) {
break;
}
//从上到下
for(int i=top;i<=bottom;i++) {
list.add(matrix[i][right]);
}
if(left>--right) {
break;
}
//从右到左
for(int i=right;i>=left;i--) {
list.add(matrix[bottom][i]);
}
if(top>--bottom) {
break;
}
//从下到上
for(int i=bottom;i>=top;i--) {
list.add(matrix[i][left]);
}
if(++left>right) {
break;
}
}
return list.stream().mapToInt(Integer::valueOf).toArray();
}