leetcode 54.螺旋矩阵
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
和剑指office29题相似;
思路:既然是顺时针遍历一圈,那么我们就分别从上边,右边,下边,左边依次遍历,一圈完后在遍历下一圈,直到符合终止条件,停止循环,过程中将遍历到的值存入集合中,返回集合即可;
大体的思路如上所示,是很简单的,但是这个题的难点在于:
1.保证边界的取值是正确的,不会出现数组越界
2.我们需要保持每次遍历时的左闭右开还是左开右闭是统一的
3.终止条件的判断,什么时候算是全部遍历完成了
首先我们需要先定义四个变量,分别是上右下左,它们分别代表遍历的当前这个圈的上右下左四个边所处的位置,每遍历一次,就对应的缩小一个位置(这里可以实现左开右闭或者左闭右开),直到我们左和右相遇,或者上和下相遇,这是就意味着每个数已经遍历完成,就是终止条件。
综上,代码如下:
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> lists = new ArrayList<>();
int m = matrix.length ;//定义行数
int n = matrix[0].length ;//定义列数
//上下左右
//注意,这里的上下左右四个值,分别指的是遍历这一行或者这一列时,保持不动的那个行数或列数
//例如我们遍历第一行时,行数是up保持不变,列数是i进行递增
int up = 0;//遍历时的点坐标[up,i]
int right = n-1;//[i,right]
int down = m-1;//[down,i]
int left = 0;//[i,left]
while (true){
//从左到右
for (int i = left; i <= right; i++) {lists.add(matrix[up][i]);}
if (++up>down){break;}//每一行或者一列遍历完后,都要缩圈,这里是上边向下缩圈
//up已经完成加1操作,向下移动了一行,因为下面的从上到下遍历,是从up这一行开始的
//所以就实现了我们的右闭,后面的以此类推;
//当移动后的up与down冲突时,意味着遍历已经结束了,break跳出循环,下面的同理。
//从上到下
for (int i = up; i <= down; i++) {lists.add(matrix[i][right]);}
if (--right<left){break;}//右边遍历完,向左缩圈
//从右到左
for (int i = right; i >= left; i--) {lists.add(matrix[down][i]);}
if (--down<up){break;}//下边遍历完,向上缩圈
//从下到上
for (int i = down; i >= up; i--) {lists.add(matrix[i][left]);}
if (++left>right){break;}//左边遍历完,向右缩圈
}
return lists;
}