LeetCode第54题:螺旋矩阵
问题描述
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
方法一(有点麻烦了)
思路分析
- 按圈进行遍历,对每一圈进行遍历时,保持左闭右开的步骤进行处理
- 最后要考虑是否会剩下中间的一行或一列需要单独进行处理
详见代码。
代码
class Solution
{
public List<Integer> spiralOrder(int[][] matrix)
{
List<Integer> retList = new ArrayList<>();
int m = matrix.length;
int n = matrix[0].length;
int loop = Integer.min(m, n) / 2;
int startx = 0;// 每一圈的遍历初始位置的行号
int starty = 0;// 每一圈的遍历初始位置的列号
int i = startx;
int j = starty;
int offset = 1;
while (loop-- > 0)
{
// 从左向右遍历,不包括最右端的值
for (j = starty; j < starty + n - offset; j++)
{
retList.add(matrix[startx][j]);
}
// 从上向下遍历,不包括最下端的值
for (i = startx; i < startx + m - offset; i++)
{
retList.add(matrix[i][j]);
}
// 从右向左遍历,不包括最左端的值
for (; j > starty; j--)
{
retList.add(matrix[i][j]);
}
// 从下向上遍历,不包括最上端的值
for (; i > startx; i--)
{
retList.add(matrix[i][j]);
}
startx++;
starty++;
offset += 2;
}
// 是否会剩余未遍历到的行或列,取决于行、列数的最小值,是否为奇数
if (Integer.min(m, n) % 2 == 1)
{
if (m < n)// 剩余某一行未进行遍历
{
for (int k = m / 2; k < m / 2 + n - m / 2 * 2; k++)
{
retList.add(matrix[m / 2][k]);
}
}
else// 剩余某一列未进行遍历
{
for (int k = n / 2; k < n / 2 + m - n / 2 * 2; k++)
{
retList.add(matrix[k][n / 2]);
}
}
}
return retList;
}
}
方法二
思路分析
- 上面方法的循环条件写得不好,因为在行数或列数为奇数时需要单独处理中间的那一行或一列。
- 下面的方法在对每行进行遍历前,判断是否越界,遍历完每行或每列后,立即对这一行(列)的边界进行处理,思路上更加清晰,代码也更简洁。
详见代码。
代码
class Solution
{
public List<Integer> spiralOrder(int[][] matrix)
{
List<Integer> retList = new ArrayList<>();
int rowBegin = 0;
int rowEnd = matrix.length - 1;
int colBegin = 0;
int colEnd = matrix[0].length - 1;
while (rowBegin <= rowEnd && colBegin <= colEnd)
{
// 从左向右遍历
for (int j = colBegin; j <= colEnd; j++)
{
retList.add(matrix[rowBegin][j]);
}
// 该行遍历完成,使这一圈的最开始一行 rowBegin+1
rowBegin++;
// 从上向下遍历
for (int i = rowBegin; i <= rowEnd; i++)
{
retList.add(matrix[i][colEnd]);
}
// 该列遍历完成,使这一圈的最后一列 colEnd-1
colEnd--;
// 从右向左遍历。需要判断是否重复遍历
if (rowBegin <= rowEnd)
{
for (int j = colEnd; j >= colBegin; j--)
{
retList.add(matrix[rowEnd][j]);
}
}
// 该行遍历完成,使这一圈的最后一行 rowEnd-1
rowEnd--;
// 从下向上遍历。需要判断是否重复遍历
if (colBegin <= colEnd)
{
for (int i = rowEnd; i >= rowBegin; i--)
{
retList.add(matrix[i][colBegin]);
}
}
// 该列遍历完成,使这一圈的最开始一列 colBegin+1
colBegin++;
}
return retList;
}
}