Optimal: shrink four boundaries
Time O(m × n) Space O(1) extra (besides the output list)Walk the top row left to right, then top++. Walk the right column top to bottom, then right--. If rows remain, walk the bottom row right to left, then bottom--. If columns remain, walk the left column bottom to top, then left++. Repeat while top <= bottom and left <= right.
import java.util.ArrayList;
import java.util.List;
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> out = new ArrayList<>();
int top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int c = left; c <= right; c++) out.add(matrix[top][c]);
top++;
for (int r = top; r <= bottom; r++) out.add(matrix[r][right]);
right--;
if (top <= bottom) {
for (int c = right; c >= left; c--) out.add(matrix[bottom][c]);
bottom--;
}
if (left <= right) {
for (int r = bottom; r >= top; r--) out.add(matrix[r][left]);
left++;
}
}
return out;
}
}Verdict: Every cell is visited exactly once.