题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

思路
https://mp.weixin.qq.com/s/F9UbsPWo8MBKebU9ctKAuQ

箭头标注的顺序就是螺旋的顺序,这道题让我们求的就是按照螺旋的顺序遍历之后的结果。
方向数组
比如我们画一个小人,它所在的坐标是(x, y),它有东南西北四个方向可以选。我们假设他每次移动一个单位的距离,我们很容易就得出它往各个方向移动之后的新坐标。
根据数学上向量的定义,我们可以写出这四个方向的方向单位向量:[0, 1], [0, -1], [1, 0], [-1, 0]。
原本朝东的旋转之后变成了朝南,朝南的变成了朝西,朝西的成了朝北,而朝北的成了朝东。那么我们只需要把方向按照东南西北的顺序摆放,我们每次把方向数组的下标增加一位并对4取模,就得到了转向之后的下一个方向。
[0, 1], [1,0], [0, -1], [-1, 0]
代码
class Solution:def spiralOrder(self, matrix: List[List[int]]) -> List[int]:fx = [[0, 1], [1,0], [0, -1], [-1, 0]] # fangxiang 东南西北# 到终点,则(dir_ind + 1) % 4n = len(matrix)if n == 0:return []m = len(matrix[0])ret = []# 定义边界数组condition = [0, m-1, n-1, 0]x, y, dt = 0, 0, 0for i in range(n * m):ret.append(matrix[x][y])x_, y_ = x + fx[dt][0], y + fx[dt][1]# 判断是否越过边界。越过则转向if x_ < condition[0] or x_ > condition[2] or y_ < condition[3] or y_ > condition[1]:# 更新边界if dt in (1, 2):condition[dt] -= 1else:condition[dt] += 1# 转向,并且重新移动dt = (dt + 1) % 4x_, y_ = x+fx[dt][0], y+fx[dt][1]x, y = x_, y_return ret
class Solution:def spiralOrder(self, matrix: List[List[int]]) -> List[int]:rows = len(matrix)if rows == 0:return []columns = len(matrix[0])start = 0 # 开始坐上角的坐标是(0, 0)global ansans = []while (columns > start * 2 and rows > start * 2):self.PrintMatrixInCircle(matrix, columns, rows, start)start += 1return ansdef PrintMatrixInCircle(self, matrix, columns, rows, start):global ansendX = columns - startendY = rows - start# 从左到右打印一行for i in range(start, endX):print(matrix[start][i])ans.append((matrix[start][i]))# 从上到下打印一列if start < endY:for i in range(start+1, endY):print(matrix[i][endX-1])ans.append(matrix[i][endX-1])# 从右到左打印一行if start < endX and start < endY-1:for i in range(endX-2, start-1, -1):print(matrix[endY-1][i])ans.append(matrix[endY-1][i])# 从下到上打印一列if start < endX-1 and start < endY - 2:for i in range(endY-2, start, -1):print(matrix[i][start])ans.append(matrix[i][start])
