题目

https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/submissions/
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵:
image.png

思路

image.png
接下来分析循环结束的条件。假设这个矩阵的行数是 rows,列数是columns。打印第一圈的左上角的坐标是(1,1),第二圈的左上角的坐标是(2, 2),依此类推。我们注意到,左上角的坐标中行标和列标总是相同的,于是可以在矩阵中选取左上角为(start,start)的一圈作为我们分析的目标。

对一个5×5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2)。我们发现5>2×2。对一个6×6的矩阵而言,最后一圈有4个数字,其左上角的坐标仍然为(2,2)。我们发现6>2×2依然成立。于是我们可以得出,让循环继续的条件是columns>startX ×2 并且rows>startY×2。

仔细分析每一步打印的前提条件,这个是重点。
image.png

代码

  1. class Solution:
  2. def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
  3. if not matrix:
  4. return matrix
  5. row, col = len(matrix), len(matrix[0])
  6. i, j = 0, 0
  7. def printCircle(start, matrix, rowBoundary=row, colBoundary=col):
  8. ans = []
  9. # left to right,总是需要从左打印
  10. for j in range(start, colBoundary):
  11. ans.append(matrix[start][j])
  12. # up to down, 至少需要两行,才需要执行从上到下打印
  13. if rowBoundary - start > 1:
  14. for i in range(start+1, rowBoundary):
  15. ans.append(matrix[i][colBoundary-1])
  16. # right to left,至少需要两行两列
  17. if rowBoundary - start > 1 and colBoundary - start > 1:
  18. for j in range(colBoundary - 2, start-1, -1):
  19. ans.append(matrix[rowBoundary-1][j])
  20. # down to up,至少需要三行两列
  21. if rowBoundary - start > 2 and colBoundary - start > 1:
  22. for i in range(rowBoundary-2, start, -1):
  23. ans.append(matrix[i][start])
  24. return ans
  25. start = 0
  26. row, col = len(matrix), len(matrix[0])
  27. result = []
  28. while row > start * 2 and col > start * 2:
  29. # print a loop
  30. circleNums = printCircle(start, matrix, rowBoundary=row-start, colBoundary=col-start)
  31. result.extend(circleNums)
  32. start += 1
  33. return result