输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
注意:本题与主站 54 题(54. 螺旋矩阵)相同:https://leetcode-cn.com/problems/spiral-matrix/
给一个
m
行n
列的矩阵matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
解题思路:模拟,设定四个边界
- 根据题目示例
matrix = [[1,2,3],[4,5,6],[7,8,9]]
的对应输出[1,2,3,6,9,8,7,4,5]
可以发现,顺时针打印矩阵的顺序是 “从左向右、从上向下、从右向左、从下向上” 循环。- 因此,考虑设定矩阵的“左、上、右、下”四个边界,模拟以上矩阵遍历顺序。
模拟打印过程:
- 空值处理: 当
matrix
为空(三种情况)时,直接返回空列表[]
即可。— new int[0]- 初始化: 矩阵 左、右、上、下 四个边界
left
,right
,top
,bottom
,用于打印的结果列表result
。- 循环打印: “从左向右、从上向下、从右向左、从下向上” 四个方向循环,每个方向打印中做以下三件事 (各方向的具体信息见下表) ;
- 根据边界打印,将元素按顺序添加至列表
result
尾部;- 边界向内收缩 1 (代表已被打印遍历);
- 判断是否打印完毕(同方向边界是否相遇,左与右 / 上与下),若打印完毕则跳出。
- 返回值: 返回
res
即可。
打印方向 | 1. 根据边界打印 | 2. 边界向内收缩 | 3. 是否打印完毕 |
---|---|---|---|
从左向右 | 左边界left ,右边界 right | 上边界 top 加 1 | 是否 top > bottom |
从上向下 | 上边界 top ,下边界bottom | 右边界 right 减 1 | 是否 left > right |
从右向左 | 右边界 right ,左边界left | 下边界 bottom 减 1 | 是否 top > bottom |
从下向上 | 下边界 bottom ,上边界top | 左边界 left 加 1 | 是否 left > right |
- 时间复杂度 O(mn) : m,n 分别为矩阵行数和列数。
- 空间复杂度 O(1) : 四个边界
left
,right
,top
,bottom
使用常数大小的 额外 空间(result
为必须使用的空间,存放返回结果)。
class Solution {
public int[] spiralOrder(int[][] matrix) {
// 判断是否为空
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
return new int[0];
}
// 计算行列的值,初始化返回结果的存储空间
int rows = matrix.length;
int colums = matrix[0].length;
int[] result = new int[rows * colums];
// 定义上下左右边界
int top = 0;
int bottom = rows - 1;
int left = 0;
int right = colums -1;
int index = 0;
while(true){
// left to right 从左向右
for(int i = left; i <= right; i ++){
result[index++] = matrix[top][i];
}
top ++;
if(top > bottom){
break;
}
// top to bottom 从上到下
for(int i = top; i <= bottom; i++ ){
result[index++] = matrix[i][right];
}
right --;
if(right < left){
break;
}
// right to left 从右到左
for(int i = right; i >=left; i --){
result[index++] = matrix[bottom][i];
}
bottom --;
if(bottom < top){
break;
}
// bottom to top 从下到上
for(int i = bottom; i >= top; i --){
result[index++] = matrix[i][left];
}
left ++;
if(left > right){
break;
}
}
return result;
}
}