题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
思路
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) % 4
n = len(matrix)
if n == 0:
return []
m = len(matrix[0])
ret = []
# 定义边界数组
condition = [0, m-1, n-1, 0]
x, y, dt = 0, 0, 0
for 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] -= 1
else:
condition[dt] += 1
# 转向,并且重新移动
dt = (dt + 1) % 4
x_, 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 ans
ans = []
while (columns > start * 2 and rows > start * 2):
self.PrintMatrixInCircle(matrix, columns, rows, start)
start += 1
return ans
def PrintMatrixInCircle(self, matrix, columns, rows, start):
global ans
endX = columns - start
endY = 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])