问题描述
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
实例一:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
实例二:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
解题思路:
- 遍历方向是按照 向右,向下, 向左,向上的规则,由外到里的。
- 重点在于对于边界的处理,而边界的范围是变化的。
代码
public List<Integer> spiralOrder(int[][] matrix) {
// 二维数组检查
if(matrix.length == 0 || matrix[0].length == 0) {
return new ArrayList();
}
// 行数
int row = matrix.length;
// 列数
int col = matrix[0].length;
// 保存返回结果
List<Integer> list = new ArrayList<Integer>();
// 特殊情况处理: 当每一行只有一个元素时。
if (col == 1) {
for (int l = 0; l < row; l++) {
list.add(matrix[l][0]);
}
return list;
}
int len = row * col;
int i = 0, j = 0;
// 遍历的圈数 , col - round - 1为边界值
int round = 0;
// 记录起始的位置
int starti = i, startj = j;
list.add(matrix[0][0]);
while(list.size() < len) {
// 向右
while(true) {
i++;
// 边界处理
if(i > col - round - 1) {
i--;j++;
if(list.size() != len) {
list.add(matrix[j][i]);
}
break;
}
list.add(matrix[j][i]);
}
if(list.size() == len) {
break;
}
// 向下
while(true) {
j++;
// 边界处理
if(j > row - round - 1) {
i--;j--;
if(list.size() != len) {
list.add(matrix[j][i]);
}
break;
}
list.add(matrix[j][i]);
}
if(list.size() == len) {
break;
}
//向左
while(true) {
i--;
if(i < round) {
i++;j--;
if(list.size() != len) {
list.add(matrix[j][i]);
}
break;
}
list.add(matrix[j][i]);
}
if(list.size() == len) {
break;
}
// 向上
while(true) {
j--;
if((starti == i && startj == j) || j < round) {
i++;j++;round++;
if(list.size() == len) {
break;
}
list.add(matrix[j][i]);
starti = i;
startj = j;
break;
}
list.add(matrix[j][i]);
}
}
return list;
}