题目

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

image.png

思路

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

image.png
箭头标注的顺序就是螺旋的顺序,这道题让我们求的就是按照螺旋的顺序遍历之后的结果。

方向数组

比如我们画一个小人,它所在的坐标是(x, y),它有东南西北四个方向可以选。我们假设他每次移动一个单位的距离,我们很容易就得出它往各个方向移动之后的新坐标。
image.png
根据数学上向量的定义,我们可以写出这四个方向的方向单位向量:[0, 1], [0, -1], [1, 0], [-1, 0]。

原本朝东的旋转之后变成了朝南,朝南的变成了朝西,朝西的成了朝北,而朝北的成了朝东。那么我们只需要把方向按照东南西北的顺序摆放,我们每次把方向数组的下标增加一位并对4取模,就得到了转向之后的下一个方向。
[0, 1], [1,0], [0, -1], [-1, 0]

代码

  1. class Solution:
  2. def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
  3. fx = [[0, 1], [1,0], [0, -1], [-1, 0]] # fangxiang 东南西北
  4. # 到终点,则(dir_ind + 1) % 4
  5. n = len(matrix)
  6. if n == 0:
  7. return []
  8. m = len(matrix[0])
  9. ret = []
  10. # 定义边界数组
  11. condition = [0, m-1, n-1, 0]
  12. x, y, dt = 0, 0, 0
  13. for i in range(n * m):
  14. ret.append(matrix[x][y])
  15. x_, y_ = x + fx[dt][0], y + fx[dt][1]
  16. # 判断是否越过边界。越过则转向
  17. if x_ < condition[0] or x_ > condition[2] or y_ < condition[3] or y_ > condition[1]:
  18. # 更新边界
  19. if dt in (1, 2):
  20. condition[dt] -= 1
  21. else:
  22. condition[dt] += 1
  23. # 转向,并且重新移动
  24. dt = (dt + 1) % 4
  25. x_, y_ = x+fx[dt][0], y+fx[dt][1]
  26. x, y = x_, y_
  27. return ret
  1. class Solution:
  2. def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
  3. rows = len(matrix)
  4. if rows == 0:
  5. return []
  6. columns = len(matrix[0])
  7. start = 0 # 开始坐上角的坐标是(0, 0)
  8. global ans
  9. ans = []
  10. while (columns > start * 2 and rows > start * 2):
  11. self.PrintMatrixInCircle(matrix, columns, rows, start)
  12. start += 1
  13. return ans
  14. def PrintMatrixInCircle(self, matrix, columns, rows, start):
  15. global ans
  16. endX = columns - start
  17. endY = rows - start
  18. # 从左到右打印一行
  19. for i in range(start, endX):
  20. print(matrix[start][i])
  21. ans.append((matrix[start][i]))
  22. # 从上到下打印一列
  23. if start < endY:
  24. for i in range(start+1, endY):
  25. print(matrix[i][endX-1])
  26. ans.append(matrix[i][endX-1])
  27. # 从右到左打印一行
  28. if start < endX and start < endY-1:
  29. for i in range(endX-2, start-1, -1):
  30. print(matrix[endY-1][i])
  31. ans.append(matrix[endY-1][i])
  32. # 从下到上打印一列
  33. if start < endX-1 and start < endY - 2:
  34. for i in range(endY-2, start, -1):
  35. print(matrix[i][start])
  36. ans.append(matrix[i][start])