Description:
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example 1:
Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,8,7,4,5]
Example 2:
Input: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] Output: [1,2,3,4,8,12,11,10,9,5,6,7]
Solution:
这道题需要我们按照顺时针螺旋方式输出一个二维数组
其实按照人解决这个问题的方法即可写出最终答案,
我们需要定义几个变量,分别为colS,colE,rowS,rowE,存储列的起点、终点,行的起点、终点,以及二维list res存放最终的输出(总是弄混column和row,column列,row行)
通俗来说,就是先把第一行的内容输出,到达该行的末位时,开始转向输入尾列的内容,到达该列的末尾时,再转向输入尾行……依次类推接下来不停转向即可
在每次转向时,由于最后一个元素既在这一行也在这一列,因此要把对应的行/列+1,防止重复输出
这样操作还有一个好处,就是通过+1将已经输出过的行/列剔除了。试想如果某行已经输出,其实已经可以当做它不存在,+1就完成的是这个操作
通过这样的操作我们也可以得到循环的条件,即rowS<=rowE,colS<=colE,因为每次操作后都+1了,如果结果为大于证明如果继续输出则会覆盖,因此需要停止输出
同时还要注意,由于每一圈一共需要循环4次(向右/下/左/上),尽管在外层判断过可以循环的条件,但是前两次的循环又改变了row/col的值,因此对于后两个循环仍需要再次判断它们需要循环的部分是否发生了覆盖
还有一点需要注意的是,开始的循环遍历的时候切记要写成start to end,而不应该写成0,删除行/列后遍历的起点就不是0了
Code:
public List<Integer> spiralOrder(int[][] matrix) { List<Integer> res = new ArrayList<>(); int n = matrix.length; if (n == 0) return res; int rowS = 0, rowE = matrix.length - 1; int colS = 0, colE = matrix[0].length - 1; while (rowS <= rowE && colS <= colE){ // 向右: 输入rowS行的所有数字 for (int i = colS; i <= colE; i++ ){ res.add(matrix[rowS][i]); } rowS++; // 向下: 输入colE行所有数字 for (int i = rowS; i <= rowE; i++ ){ res.add(matrix[i][colE]); } colE--; // 向左: 输入rowE行所有数字 if (rowS <= rowE){ for (int i = colE; i >= colS; i-- ){ res.add(matrix[rowE][i]); } } rowE--; // 写在if内外都可以 // 向上: 输入colS行所有数字 if (colS <= colE){ for (int i = rowE; i >= rowS; i--){ res.add(matrix[i][colS]); } } colS++; } return res; }
提交情况: