前言
关于螺旋矩阵,这道算法题,当初出去面试碰到了两次,怪自己当初面完试没有及时回来总结整理。导致两次遇到了这个原题,两次都没答上来。最近自己开始在LeetCode上刷算法题,又刷到了这道题,经过整理总结后,拿到这里和大家分享一下。
废话不多说,上题:
题目
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
分析
可以仔细观察示例1或示例2,这里为了方便,咱们再多写一组示例:
示例3:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13,14, 15, 16]
]
输出: [1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10]
仔细观察可以发现,螺旋矩阵正如其名,它是按照螺旋输出矩阵中的数字。而且是有规律的,分四步:
第一步:先输出最顶部的一行(从左到右),依次是[1,2,3,4];
第二步:再输出最右边的一列(从上到下,除去最顶部已经输出的4),依次是[8,12,16];
第三步:再输出最底部一行(从右到左,除去最右边已经输出的16),依次是[15,14,13];
第四步:再输出最左边一列(从下到上,除去最底部已经输出的13和最顶部已经输出的1),依次是[9,5];
好了,这样经过四步就已经完成了螺旋矩阵的第一圈螺旋的输出,接下来,还有未输出的[6,7,11,10],又可以看作螺旋矩阵的第二圈螺旋的输出,继续重复上述四步就可以把[6,7,11,10]输出。
由分析得出结论:经过分析可知,其实螺旋矩阵的输出,分别先后对应上、右、下、左的输出,而且是一圈绕一圈,循环输出。
实现预想:可以把螺旋矩阵,看成一个二维数组结构,其实就是通过循环打印二维数组结构中元素的输出。只不过这个输出是按照上、右、下、左的顺序输出,循环进行。
具体实现
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> resultList=new ArrayList();
if(matrix==null||matrix.length==0){//判空
return resultList;
}
/**
*分别定义左、右、上、下的四个范围的初始索引
*/
int left=0;
int right=matrix[0].length-1;
int top=0;
int bottom=matrix.length-1;
while(true){//进行循环
//打印顶部数据
for(int i=left;i<=right;i++){
resultList.add(matrix[top][i]);
}
if(++top>bottom){//进行判断,如果顶部索引+1大于底部索引时,就跳出循环
break;
}
//打印右边数据
for(int i=top;i<=bottom;i++){
resultList.add(matrix[i][right]);
}
if(--right<left){//进行判断,如果右边索引-1小于左边索引时,就跳出循环
break;
}
//打印底部数据
for(int i=right;i>=left;i--){
resultList.add(matrix[bottom][i]);
}
if(--bottom<top){//进行判断,如果底部索引-1小于顶部索引时,就跳出循环
break;
}
//打印左边数据
for(int i=bottom;i>=top;i--){
resultList.add(matrix[i][left]);
}
if(++left>right){//进行判断,如果左边索引+1大于右边索引时,就跳出循环
break;
}
}
return resultList;
}
}
总结
好了,到这里关于螺旋矩阵的这道题的解答就和大家分享完毕了,其实就是一个螺旋循环去输出一个二维数组。关键在于理解算法中的螺旋顺序输出,以及跳出循环的条件。菜鸟一个,大家有什么问题可以留言,多多指教。