[Java恶补day20] 54. 螺旋矩阵
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
知识点:
数组、矩阵、标记
解:
术语定义:1个轮回=执行1次上、右、下、左
核心思路:用四个变量top、right、bottom、left,表示当前遍历的顶行、右列、底行、左列。在一个while循环内(可能需要多个轮回),通过四个并列for循环,分别执行顶行、右列、底行、左列的遍历。在每个遍历的for循环后,需要更新变量(遍历顶行后,需要更新top,这样下一次就是遍历下面一行的元素。以此类推),并判断若top>bottom、right<left、bottom<top、left>right,表示当前已遍历完毕,需要退出while循环。
测试用例1分析(遍历方向
中,逗号左边表示当前遍历的行/列。逗号右边表示当前的遍历方向):
测试用例2分析(遍历方向
中,逗号左边表示当前遍历的行/列。逗号右边表示当前的遍历方向):
时间复杂度: O ( m n ) O(mn) O(mn)。遍历所有元素。
空间复杂度: O ( 1 ) O(1) O(1)。未使用辅助数组,仅使用辅助变量。
class Solution {public List<Integer> spiralOrder(int[][] matrix) {//获取矩阵的行数、列数int m = matrix.length;int n = matrix[0].length;//定义结果列表List<Integer> res = new ArrayList<>();//特殊情况判断if (matrix == null || m == 0) {return res;}//定义当前遍历的行的左端点、右端点 / 列的上端点、下端点int top = 0;int bottom = m - 1;int left = 0;int right = n - 1;while (true) {//动作1:从左到右遍历顶行for (int i = left; i <= right; i++) {res.add(matrix[top][i]);}top++;//更新,下一个轮回将执行下边一行if (top > bottom) {//退出循环,此时已完成操作break;}//动作2:从上到下遍历右列for (int i = top; i <= bottom; i++) {res.add(matrix[i][right]);}right--;//更新,下一个轮回将执行左边一列if (right < left) {//退出循环,此时已完成操作break;}//动作3:从右到左遍历底行for (int i = right; i >= left; i--) {res.add(matrix[bottom][i]);}bottom--;//更新,下一个轮回将执行上边一行if (bottom < top) {//退出循环,此时已完成操作break;}//动作4:从下到上遍历左列for (int i = bottom; i >= top; i--) {res.add(matrix[i][left]);}left++;//更新,下一个轮回将执行右边一列if (left > right) {//退出循环,此时已完成操作break;}}return res;}
}
参考:
1、题解