【题目】
给你一个 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.lengthn == matrix[i].length1 <= m, n <= 10-100 <= matrix[i][j] <= 100
【题目解析】
解题方法
解决螺旋矩阵问题的关键是模拟遍历过程,维护四个变量left、right、top、bottom来表示当前遍历的边界,并按顺序遍历四个边界上的元素。通过逐渐缩小边界,我们可以模拟整个顺时针遍历的过程。
- 步骤一:从左到右遍历上边界的所有元素。
- 步骤二:从上到下遍历右边界的所有元素。
- 步骤三:如果适用,从右到左遍历下边界的所有元素。
- 步骤四:如果适用,从下到上遍历左边界的所有元素。
- 循环条件:每次遍历完成后,相应地缩小边界,直到边界不再重叠。
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return []
rows, cols = len(matrix), len(matrix[0])
left, right, top, bottom = 0, cols - 1, 0, rows - 1
result = []
while left <= right and top <= bottom:
# 从左到右遍历上层边界
for col in range(left, right + 1):
result.append(matrix[top][col])
# 从上到下遍历右侧边界
for row in range(top + 1, bottom + 1):
result.append(matrix[row][right])
if left < right and top < bottom:
# 从右到左遍历下层边界
for col in range(right - 1, left, -1):
result.append(matrix[bottom][col])
# 从下到上遍历左侧边界
for row in range(bottom, top, -1):
result.append(matrix[row][left])
left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1
return result
执行效率
【总结】
适用问题类型
螺旋矩阵问题属于数组遍历与矩阵操作的范畴,特别是在需要按照特定顺序访问矩阵元素的场合。此类问题广泛出现在图像处理、数据转换、以及任何涉及二维数据结构操作的领域中。
解决算法
-
算法描述:模拟遍历法通过模拟顺时针螺旋的路径来遍历矩阵中的所有元素。算法核心在于动态调整遍历的边界,即上下左右四个方向的界限,从而实现整个矩阵的顺序遍历。
-
算法特点:
- 直观性:该算法的逻辑简单直观,易于理解和实现。
- 灵活性:通过调整遍历的方向和边界条件,该方法可以应用于不同形状和大小的矩阵。
- 无需额外空间:除了输出结果所需的空间外,算法本身不需要额外的数据结构。
时间复杂度与空间复杂度
- 时间复杂度:
O(m*n),其中m和n分别代表矩阵的行数和列数。算法需要遍历矩阵中的每个元素一次。 - 空间复杂度:
O(1),算法在遍历过程中仅需维护几个变量来记录边界和方向,因此空间复杂度为常数级别。
实践意义
- 广泛应用:模拟遍历法不仅适用于螺旋矩阵问题,还可以灵活应用于其他需要特定顺序访问数据的场景,如旋转图像、填充螺旋矩阵等。
- 算法教学:该问题及其解法是教授数组和矩阵操作、掌握循环和边界控制技巧的良好案例。
- 编程技巧:掌握这种模拟遍历的方法有助于提升解决实际问题的能力,尤其是在处理复杂数据结构和算法设计时。
通过对螺旋矩阵问题的深入分析,我们不仅能够学习到如何有效地处理矩阵和数组中的数据,还能够理解到算法设计中的边界控制和循环遍历技巧,为解决更复杂的算法问题打下坚实的基础。