1:题目描述
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。(力扣)
2:解题思路
这个题目需要考虑以下四个问题
- 起始位置
- 移动方向
- 边界
- 结束条件
1:起始位置
螺旋矩阵的遍历起点是矩阵的左上角,即(0,0)的位置
2:移动方向
起始位置的下一个移动方向是向右,在遍历过程中,移动方向是固定的,即右(→)、下(↓)、左(←)、上(↑)。移动方向是按照这个顺序进行循环的,每次移动到了边界才会改变方向。
3:边界
边界是随着遍历的过程而变化的,螺旋遍历的时候,已经遍历的数字不能再次遍历,所以边界会越来越小。
规则是:如果当前行(列)遍历结束之后,就需要把这一行(列)的边界向内移动一行(列)
使用left、right、up、down来表示左右上下四个方向的边界,初始时分别指向矩阵的四个边界,初始值为:left=0,right=矩阵列数-1,up=0,down=矩阵行数-1。1:从起始位置开始向右遍历,当我们把第一行遍历结束(遍历到了右边界),此时需要改变移动方向:向下,并把上边界向下移动一行(即up+1):2:接着向下遍历,把最后一列遍历结束(遍历到了下边界),此时需要改变移动方向:向左,并把右边界向左移动一列(即right-1):3:接着向左遍历,把最后一行遍历结束(遍历到了左边界),此时需要改变移动方向:向上,并把下边界向上移动一行(即down-1):4:接着向上遍历,遍历第一列结束(遍历到上边界),此时需要改变移动方向:向右,并把左边界向右移动一列(即left+1)。
4:结束条件
按照第3步的顺序进行循环取值,直到把矩阵中的值全部取出。
代码展示:
class Solution():
def spiralOrder(self, matrix):
if not matrix or not matrix[0]: return []
# 获取数组的行数和列数
row, rol = len(matrix), len(matrix[0])
# 初始化左右上下四个边界的初始值,左边界和上边界的初始值为0,右边界的初始值为:列数-1,下边界的初始值为:行数-1
left, right, up, down = 0, rol-1, 0, row-1
# 初始化起始位置的下标,x,y
x, y = 0, 0
# 定义方向,右:(0, 1), 下:(1, 0), 左:(0, -1), 上(-1, 0)
dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
# cur_d用来控制方向
cur_d = 0
# 定义一个存放元素的新数组
res = []
while len(res) != row * rol: # 当新数组的长度不等于matrix数组的个数时,进入循环
res.append(matrix[x][y])
if cur_d == 0 and y == right:
# 向右进行取值,x不变,y递增,直到y的值等于右边界的值
# 改变取值方向
cur_d += 1
# 到达右边界,修改上边界的值
up += 1
elif cur_d ==1 and x == down:
# 向下取值,y不变,x递增,直到x的值等于下边界的值
# 改变取值方向
cur_d += 1
# 到达下边界,修改右边界的值
right -= 1
elif cur_d ==2 and y == left:
# 向左取值,x不变,y递减,直到y的值等于左边界的值
# 改变取值方向
cur_d += 1
# 到达左边界,修改下边界的值
down -= 1
elif cur_d ==4 and x == up:
# 向上取值,y不变,x递减,直到x的值等于上边界的值
# 改变取值方向
cur_d += 1
# 到达上边界,修改左边界的值
left += 1
# 一共四个方向进行循环取值,所以需要保证,一轮方向取值完成后,能再从右开始取值
cur_d %= 4
# 修改每次取值的下标
x += dirs[cur_d][0]
y += dirs[cur_d][-1]
return res