LeetCode 热题 100 54. 螺旋矩阵
LeetCode 热题 100 | 54. 螺旋矩阵
大家好,今天我们来解决一道经典的算法题——螺旋矩阵。这道题在LeetCode上被标记为中等难度,要求我们按照顺时针螺旋顺序返回矩阵中的所有元素。下面我将详细讲解解题思路,并附上Python代码实现。
问题描述
给定一个 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]
解题思路
核心思想
-
边界模拟法:
- 定义矩阵的四个边界:上边界
top
、下边界bottom
、左边界left
、右边界right
。 - 按照顺时针方向(右→下→左→上)依次遍历矩阵的边界,并不断调整边界。
- 定义矩阵的四个边界:上边界
-
遍历顺序:
- 从左到右遍历上边界,完成后上边界下移。
- 从上到下遍历右边界,完成后右边界左移。
- 从右到左遍历下边界,完成后下边界上移。
- 从下到上遍历左边界,完成后左边界右移。
-
终止条件:
- 当所有元素都被遍历时(即
top > bottom
或left > right
),停止遍历。
- 当所有元素都被遍历时(即
Python代码实现
def spiralOrder(matrix):if not matrix:return []top, bottom = 0, len(matrix) - 1left, right = 0, len(matrix[0]) - 1result = []while top <= bottom and left <= right:# 从左到右遍历上边界for i in range(left, right + 1):result.append(matrix[top][i])top += 1# 从上到下遍历右边界for i in range(top, bottom + 1):result.append(matrix[i][right])right -= 1# 检查是否还有下边界需要遍历if top <= bottom:# 从右到左遍历下边界for i in range(right, left - 1, -1):result.append(matrix[bottom][i])bottom -= 1# 检查是否还有左边界需要遍历if left <= right:# 从下到上遍历左边界for i in range(bottom, top - 1, -1):result.append(matrix[i][left])left += 1return result# 测试示例
matrix1 = [[1,2,3],[4,5,6],[7,8,9]]
matrix2 = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]print(spiralOrder(matrix1)) # 输出: [1,2,3,6,9,8,7,4,5]
print(spiralOrder(matrix2)) # 输出: [1,2,3,4,8,12,11,10,9,5,6,7]
代码解析
-
初始化边界:
top
和bottom
分别表示矩阵的上下边界。left
和right
分别表示矩阵的左右边界。
-
顺时针遍历:
- 从左到右:遍历上边界,完成后将
top
下移。 - 从上到下:遍历右边界,完成后将
right
左移。 - 从右到左:遍历下边界(需检查
top <= bottom
),完成后将bottom
上移。 - 从下到上:遍历左边界(需检查
left <= right
),完成后将left
右移。
- 从左到右:遍历上边界,完成后将
-
终止条件:
- 当
top > bottom
或left > right
时,说明所有元素已被遍历。
- 当
复杂度分析
- 时间复杂度:O(m × n),其中
m
是矩阵的行数,n
是矩阵的列数。我们需要遍历矩阵中的每个元素一次。 - 空间复杂度:O(1),除了输出结果外,只使用了常数个额外空间。
示例运行
示例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]
进阶:其他解法
方法一:递归法
def spiralOrder_recursive(matrix):if not matrix:return []result = []rows, cols = len(matrix), len(matrix[0])def helper(top, bottom, left, right):if top > bottom or left > right:return# 从左到右遍历上边界for i in range(left, right + 1):result.append(matrix[top][i])top += 1# 从上到下遍历右边界for i in range(top, bottom + 1):result.append(matrix[i][right])right -= 1# 检查是否还有下边界需要遍历if top <= bottom:# 从右到左遍历下边界for i in range(right, left - 1, -1):result.append(matrix[bottom][i])bottom -= 1# 检查是否还有左边界需要遍历if left <= right:# 从下到上遍历左边界for i in range(bottom, top - 1, -1):result.append(matrix[i][left])left += 1helper(top, bottom, left, right)helper(0, rows - 1, 0, cols - 1)return result
- 时间复杂度:O(m × n)
- 空间复杂度:O(min(m, n)),递归调用的栈空间。
总结
通过使用边界模拟法,我们可以高效地按照顺时针螺旋顺序遍历矩阵中的所有元素。这种方法直观且易于实现,适合大多数场景。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!
关注我,获取更多算法题解和编程技巧!