题目
给你一个 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
解题思路
防止出现屎山代码,使用count计数,当count等于矩阵内数字的数量时,立刻返回结果集合。在完成一行或一竖的数字遍历时,才会出现count满足条件的情况。
当矩阵内只有一个元素时,单独处理,直接将此元素加入集合,返回集合。
1.左向右:左闭右闭
for (j = starty; j <= leny - offset; j++){ res.add(matrix[i][j]); count++; } j--;
每次循环的第一行将整行的元素加入集合,这样就不会出现样例单行或单列丢失元素的情况。在遍历后j为leny - offset + 1的状态,因此要减一。
offset为限制每次大循环中4个行列的遍历元素数。
2.上向下:上开下闭
for (i = startx + 1; i <= lenx - offset; i++){ res.add(matrix[i][j]); count++; } i--; j--;
因上开,所以i初始值为startx + 1,意为上向下遍历时不取右上第一个
因下闭,所以j要减一,意为右向左横向遍历时不取右下第一个
3.右向左:右开左闭
for (;j >= starty; j--){ res.add(matrix[i][j]); count++; } i--; j++;
同理
4.下向上:下开上开
for (;i > startx; i--){ res.add(matrix[i][j]); count++; }
offset++; startx++; starty++;
每次大循环后,更新offset和下次大循环的初始位置的取值。
代码
public static List<Integer> spiralOrder(int[][] matrix) {
int lenx = matrix.length;
int leny = matrix[0].length;
int n = leny * lenx;
List<Integer> res = new ArrayList<Integer>();
if (n == 1){
res.add(matrix[0][0]);
return res;
}
int offset = 1;
int startx = 0, starty = 0;
int i, j;
int count = 0;
while(count != n){
i = startx;
j = starty;
for (j = starty; j <= leny - offset; j++){
res.add(matrix[i][j]);
count++;
}
j--;
if (count == n)return res;
for (i = startx + 1; i <= lenx - offset; i++){
res.add(matrix[i][j]);
count++;
}
i--;
j--;
if (count == n)return res;
for (;j >= starty; j--){
res.add(matrix[i][j]);
count++;
}
i--;
j++;
if (count == n)return res;
for (;i > startx; i--){
res.add(matrix[i][j]);
count++;
}
offset++;
startx++;
starty++;
}
return res;
}