题目
查看题目
思路
- 坑:要看清楚题目要求,顺时针打印矩阵而不是方阵,所以行和列的长度不一样,要单独进行判断,千万别当成方阵进行求解。
具体算法
- ** 空值处理**:当
matrix
为空时,直接返回空列表[ ]
即可(可以判断行和列的长度是否为0,注意判断顺序,先行后列)。 - 初始化: 矩阵 左、右、上、下四个边界
l,r,t,b
,用来存储的ArrayList
列表res
。 - 循环打印:“从左到右,从上到下,从右到左,从下到上”四个方向循环,每个方向打印中做一下三件事(不同方向的具体操作如表);
- 根据边界打印,即将元素按顺序添加
res
尾部; - 边界向内收缩1(代表已被打印);
- 判断是否打印完毕(边界是否相遇,注意判断的是对向的边界,即从左到右移动时,判断上下 边界是否已经重合),若打印完毕则跳出。
- 返回值: 因为没法将ArrayList直接转换为
int
类型,所以只能用流的方式进行转换。
打印方向 | 根据边界打印 | 边界向内收缩 | 是否打印完毕 |
---|
从左到右 | 左边界l ,右边界r | 上边界t 加1 | 是否t > b |
从上到下 | 上边界t ,下边界b | 右边界r 减1 | 是否l > r |
从右到左 | 右边界r ,左边界l | 下边界b 减1 | 是否t > b |
从下到上 | 下边界b ,上边界t | 左边界l 加1 | 是否l > r |
复杂度分析
- 时间复杂度 O(MN) : M, NM,N 分别为矩阵行数和列数。
- 空间复杂度 O(1) : 四个边界 l , r , t , b 使用常数大小的 额外 空间( res 为必须使用的空间)。
代码
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0 ) return new int[0];
int heng = matrix.length;
int zong = matrix[0].length;
int l = 0;
int r = zong - 1;
int t = 0;
int b = heng - 1;
int sum = 1;
ArrayList<Integer> res = new ArrayList<Integer>();
while(true){
for(int j = l; j <= r; j++){
res.add(matrix[t][j]);
}
t++;
if(t > b) break;
for(int j = t; j <= b; j++){
res.add(matrix[j][r]);
}
r--;
if(l > r) break;
for(int j = r; j >= l; j--){
res.add(matrix[b][j]);
}
b--;
if(t > b) break;
for(int j = b; j >= t; j--){
res.add(matrix[j][l]);
}
l++;
if(l > r) break;
}
int[] res_arr = res.stream().mapToInt(Integer::intValue).toArray();
return res_arr;
}
}