```
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> list = new LinkedList<Integer>();
if(matrix.length == 0)
return list;
//direction belongs to {0,1,2,3}
// 0: increase x; 1: increase y; 2:decrease x; 3: decrease y
int direction = 0;
int m = matrix.length;
int n = matrix[0].length;
//end[1] is the end of pos = 0; or the end of move along x axis increasingly
// move util x = n-1, pos should add 1, and then move downward y axis
int[] end = {0,n-1,m-1,0};
//direction = 0, increase x, X[0] = 1.
//-1 means decrease;
int[] X = {1,0,-1,0};
int[] Y = {0,1,0,-1};
//initial
int x = -1;
int y = 0;
for(int i = 0; i < m*n; i ++)
{
x = X[direction] + x;
y = Y[direction] + y;
list.add(matrix[y][x]);
//move along direction till the end
if(Math.abs(X[direction]) * x + Math.abs(Y[direction]) * y == end[(direction + 1)%4])
{
//the current line has been covered, so the end should change.
end[direction] += X[direction] + (-1)*Y[direction];
direction = (direction + 1) % 4;
}
}
return list;
}
```