螺旋矩阵
· 约 2 分钟阅读 · – 次阅读
leetcode
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
示例 2: 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
四次旋转模拟法
第一次:从左到右,横坐标不变,纵坐标+1 第二次:从上到下,纵坐标不变,横坐标+1 第三次:从右到左,横坐标不变,纵坐标-1 第四次:从下到上,纵坐标不变,横坐标-1
思路比较清晰,比较容易理解
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
rows = len(matrix)
columns = len(matrix[0])
total = rows * columns
left = 0
right = columns - 1
top = 0
bottom = rows - 1
result = []
while total > 0:
for i in range(left, right+1):
# 通过总数控制循环是否停止
if total == 0:
break
# print(top, i)
result.append(matrix[top][i])
total = total - 1
# 每次循环完成后,某一个坐标需要改变
top += 1
for i in range(top, bottom+1):
if total == 0:
break
# print(i, right)
result.append(matrix[i][right])
total = total - 1
right = right - 1
for i in range(right, left-1, -1):
if total == 0:
break
# print(bottom, i)
result.append(matrix[bottom][i])
total = total - 1
bottom = bottom - 1
for i in range(bottom, top-1, -1):
if total == 0:
break
# print("----", i, left)
result.append(matrix[i][left])
total = total - 1
left += 1
return result
逻辑优化后的模拟
其实代码初始理解起来并不直观,但是写起来比较舒适
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
rows = len(matrix)
columns = len(matrix[0])
total = rows * columns
visited = [[False]*columns for _ in range(rows)]
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
row = 0
column = 0
direction_index = 0
result = []
for i in range(total):
result.append(matrix[row][column])
visited[row][column] = True
next_row = row + directions[direction_index][0]
next_column = column + directions[direction_index][1]
# 如果超出边界或者数据已经访问过,则表示需要转换规则
if next_row >= rows or next_row < 0 or next_column >= columns or next_column < 0 or visited[next_row][next_column]:
direction_index = (direction_index+1)%4
row += directions[direction_index][0]
column += directions[direction_index][1]
return result
按层模拟
可以将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。 定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。 访问完一层以后,再访问里面一层,也算是一个思路。但是其实没有第一种直观。
(略过, 后面再训练这种思路)