之前也写过一篇关于这道题的博客,不过没有这篇方法好:https://blog.csdn.net/PMPWDF/article/details/80154608
题目描述:
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
题目解析:
这道题的核心思想是,由起点坐标、方向、位移可以定义矩阵中的唯一一条线段,并且可知当前路径下的所有坐标;而螺旋的过程可以抽象为访问多条首尾相连的线段,并且这些线段有如下特征:
- 起点坐标可知:因为多条路线首尾相连,所以下一个线段的起点为上一个线段的尾巴。
- 方向可知:总是按照向右、 向下、 向左、 向上循环切换。
- 位移可知:横向位移为矩阵的宽度、纵向位移为矩阵的高度,并且总是可以根据当前线段的方向,修正之后矩阵的参数。0横向:高度-1 ,纵向:宽度-1
- 总位移与矩阵的面积相等。
Python代码实现:
def spiralOrder(matrix):
result = []
height = len(matrix)
if height == 0:
width = 0
else:
width = len(matrix[0])
size = height*width
#顺时针方向x和y的变化
dirX = [0,1,0,-1]
dirY = [1,0,-1,0]
#初始化起点坐标:(0,-1) 方向:向右
x, y, dir = 0, -1, 0
total = 0
while total < size:
if dir == 0 or dir ==2:
#step是每次转折后要走几步
step = width
#当开始走一行时,矩阵的高要减一
height -= 1
else:
step = height
# 当开始走一列时,矩阵的宽要减一
width -=1
for i in range(step,0,-1):
x += dirX[dir]
y += dirY[dir]
result.append(matrix[x][y])
#取余,当dir>=4时,即已经至少转一圈了,保持right down left up
dir = (dir+1)%4
#每遍历完一行或一列加上遍历的元素个数
total += step
for i in range(len(result)):
print(result[i])
if __name__ == "__main__":
matrix = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
spiralOrder(matrix)
复杂度分析:
- 时间复杂度:O(N2),其中 N 是输入矩阵所有元素的个数。
- 空间复杂度:O(N),存储结果集 result 。