这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战
前言
力扣第五十四题 螺旋矩阵
如下所示:
给你一个 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
行 n
列的矩阵共有多少个圈呢?
如 3 x 4
的矩阵有 2
个圈
一个 4 x 4
的矩阵也有 2
个圈
从上面我们可以得出,m x n
的矩阵有的圈数为:如果较小边长为偶数,则圈数为较小的边长除以 2
。如果较小边长为偶数,则圈数为较小的边长除以 2
再加 1
通过上面的两个步骤我们知道了需要遍历的圈数和遍历的顺序,所以大致的步骤分为以下两步:
- 按圈数,从外至内
- 当前圈中按照
→
、↓
、←
、↑
的顺序遍历
举个例子
此处以示例2中 matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
作为例子,矩阵如下所示:
- 遍历外圈1,从左至右。可以获得元素
{1, 2, 3, 4}
- 遍历外圈1,从上至下。可以获得元素
{8, 12}
(需注意此处的起始处为i+1
,不能再获取4
了)
- 遍历外圈1,从右至左。可以获得元素
{11, 10, 9}
(需注意此处的起始处为(m-1)-i
,不能再获取12
了)
- 遍历外圈1,从下至上。可以获得元素
{5}
(需注意此处不能再获取底部的9
和顶部的1
了)
- 遍历外圈2,从左至右。可以获得元素
{6, 7}
- 最终,返回结果
{1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7}
即可
二、实现
实现代码
实现代码与思路中保持一致
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> ret = new ArrayList<>(); // 结果集
if(matrix == null || matrix.length == 0)
return ret;
int m = matrix.length; // 行
int n = matrix[0].length; // 列
int i = 0;
int minLen = Math.min(m, n);
// 共有多少个圈(如果为奇数会多一圈)
int count = minLen % 2 > 0 ? minLen/ 2 + 1 : minLen/2;
// 从外部向内逐层遍历
while(i < count) {
// 向左
for (int j = i; j < n-i; j++) {
ret.add(matrix[i][j]);
}
// 向下
for (int j = i+1; j < m-i; j++) {
ret.add(matrix[j][(n-1)-i]);
}
// 向左
for (int j = (n-1)-(i+1); j >= i && (m-1-i != i); j--) {
ret.add(matrix[(m-1)-i][j]);
}
// 向上
for (int j = (m-1)-(i+1); j >= i+1 && (n-1-i) != i; j--) {
ret.add(matrix[j][i]);
}
i++;
}
return ret;
}
测试代码
public static void main(String[] args) {
int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
new Number54().spiralOrder(matrix);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥