public ArrayList<Integer> spiralOrder(int[][] matrix) {
//
ArrayList<Integer> result = new ArrayList<Integer>();
if(matrix == null) return result;
if(matrix.length < 1) return result;
int rowNum = matrix.length, colNum = matrix[0].length;
boolean[][] flags = new boolean[matrix.length][matrix[0].length];
int left = 0, right = matrix[0].length, up = 0, down = matrix.length;
int direction = 1; // 1 right, 2 down, 3 left, 4 up
int curRow = 0, curCol = 0;
boolean going = true;
while(going) {
if(direction == 1) {
//store num
if(!flags[curRow][curCol]) {
result.add(matrix[curRow][curCol]);
flags[curRow][curCol] = true;
}
//judge direction
if(curCol+1 == colNum || flags[curRow][curCol+1]) { //has to turn down
if(curRow + 1 == rowNum) {going = false; continue;}
if(flags[curRow+ 1][curCol]) {going = false; continue;}
else {
direction = 2; continue;
}
} else {
curCol++;
continue;
}
} else if(direction == 2) {
//store num
if(!flags[curRow][curCol]) {
result.add(matrix[curRow][curCol]);
flags[curRow][curCol] = true;
}
//judge direction
if(curRow + 1 == rowNum || flags[curRow+1][curCol]) { // has to turn
if(curCol == 0) { going = false; continue;}
if(flags[curRow][curCol - 1]) {going = false; continue;}
else {
direction = 3; continue;
}
} else {
curRow++;
continue;
}
} else if(direction == 3) {
//store num
if(!flags[curRow][curCol]) {
result.add(matrix[curRow][curCol]);
flags[curRow][curCol] = true;
}
//judge direction
if(curCol == 0 || flags[curRow][curCol-1]) { //has to turn up
if(curRow == 0) {going = false; continue;}
if(flags[curRow - 1][curCol]) {going = false; continue;}
else {
direction = 4; continue;
}
} else {
curCol--; continue;
}
} else if(direction == 4) {
//store num
if(!flags[curRow][curCol]) {
result.add(matrix[curRow][curCol]);
flags[curRow][curCol] = true;
}
//judge direction
if(curRow == 0 || flags[curRow - 1][curCol]) { //has to turn right
if(curCol == colNum) { going = false; continue;}
if(flags[curRow][curCol + 1]) {going = false; continue;}
else {
direction = 1; continue;
}
} else {
curRow--;continue;
}
}
}
return result;
}