Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
[分析]
思路1:螺旋遍历就是从外到内一圈圈顺时针遍历,记每一圈起始的坐标为xStart, yStart, 每一圈x方向半径为xRadius, y方向半径为yRadius,则下一圈的起始坐标是xStart+1, yStart+1, x和y方向半径分别是xRadius-2,yRadius-2,循环直到圈任一半径为0。实现时要注意corner case,最后一圈只有一行或者一列,因此要break出来否则最后一圈会添加重复元素。
思路2:参考 https://leetcode.com/discuss/12228/super-simple-and-easy-to-understand-solution 代码更简洁易写。需要注意的是给定matrix长宽可能不相同,因此外层循环需要判断rowStart <= rowEnd && colStart <= colEnd,缺一不可,而在Spiral Matrix II中由于长宽相等,故判断一个即可。
public class Solution {
// Method 1
public List<Integer> spiralOrder1(int[][] matrix) {
List<Integer> ret = new ArrayList<Integer>();
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return ret;
int xStart = 0, yStart = 0;
int xRadius = matrix[0].length, yRadius = matrix.length;
while (xRadius > 0 && yRadius > 0) {
int i = yStart, j = xStart;
// move left
int upRightEdge = xStart + xRadius;
while (j < upRightEdge) {
ret.add(matrix[i][j++]);
}
j--;
if (yRadius == 1) break;
// move down
int downRightEdge = yStart + yRadius;
while (++i < downRightEdge) {
ret.add(matrix[i][j]);
}
i--;
if (xRadius == 1) break;
// move right
while (--j >= xStart) {
ret.add(matrix[i][j]);
}
j++;
// move up
while (--i > yStart) {
ret.add(matrix[i][j]);
}
i++;
// update info to start next spiral
xStart++;
yStart++;
xRadius -= 2;
yRadius -= 2;
}
return ret;
}
//Method 2
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> ret = new ArrayList<Integer>();
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return ret;
int rowStart = 0, rowEnd = matrix.length - 1;
int colStart = 0, colEnd = matrix[0].length - 1;
while (rowStart <= rowEnd && colStart <= colEnd) {
for (int j = colStart; j <= colEnd; j++) {//move right
ret.add(matrix[rowStart][j]);
}
rowStart++;
for (int i = rowStart; i <= rowEnd; i++) {//move down
ret.add(matrix[i][colEnd]);
}
colEnd--;
if (rowEnd >= rowStart) {
for (int j = colEnd; j >= colStart; j--) {//move left
ret.add(matrix[rowEnd][j]);
}
rowEnd--;
}
if (colEnd >= colStart) {
for (int i = rowEnd; i >= rowStart; i--) {//move up
ret.add(matrix[i][colStart]);
}
colStart++;
}
}
return ret;
}
}