顺时针打印矩阵(3种思路4个写法)
问题简述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。详细描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 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]
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。思路1:螺旋遍历
循环遍历 4 个方向的路线,中间做好边界判断(虽然思路简单,但是写起来很容易出错);
Python:写法1(更朴素)
class Solution:
def spiralOrder(self, matrix: [[int]]) -> [int]:
""""""
ret = []
if not matrix or not matrix[0]:
return ret
m, n = len(matrix), len(matrix[0]) # m行n列
# 设置左、右、上、下边界
l, r, t, b, = 0, n - 1, 0, m - 1
while True:
# 依次遍历 4 个方向
# 因为最后一趟遍历哪个方向都有可能,所以需要 4 个 break
# left to right, top+=1
for i in range(l, r + 1):
ret.append(matrix[t][i])
t += 1
if t > b:
break
# top to bottom, right-=1
for i in range(t, b + 1):
ret.append(matrix[i][r])
r -= 1
if l > r:
break
# right to left, bottom-=1
for i in range(r, l - 1, -1): # 逆序
ret.append(matrix[b][i])
b -= 1
if t > b:
break
# bottom to top, left+=1
for i in range(b, t - 1, -1): # 逆序
ret.append(matrix[i][l])
l += 1
if l > r:
break
return ret写法 1 的逻辑足够清晰,但不够通用(优雅),比如要遍历 8 个方向时;
另一种写法会预先定义各方向的 step,详见代码;
Python:写法2(更优雅)
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return []
# 4 个方向的 step
steps = [(0, 1), (1, 0), (0, -1), (-1, 0)]
m, n = len(matrix), len(matrix[0])
# 法1)使用一个 set 或矩阵记录已经访问过的位置
# visited = set()
# visited = [[False] * n for _ in range(m)] # m行n列
# 法2)直接在 matrix 上修改访问过的位置
visited = 10001
ret = []
i, j = 0, 0 # 记录当前访问的位置
k = 0 # 已经访问过的位置数量
d = 0 # 方向标记
while k < m * n:
ret.append(matrix[i][j])
matrix[i][j] = visited
# visited.add((i, j))
# visited[i][j] = True
k += 1
# 下一个位置
nxt_i, nxt_j = i + steps[d][0], j + steps[d][1]
# 判断下一个位置是否合法,或是否访问过
if not 0 <= nxt_i < m or not 0 <= nxt_j < n or matrix[nxt_i][nxt_j] == visited:
# 如果不合法或已经访问过,进入下一个方向
d = (d + 1) % 4
nxt_i, nxt_j = i + steps[d][0], j + steps[d][1]
i, j = nxt_i, nxt_j
return ret思路2:层层递归
每次遍历完最外圈后,递归遍历下一圈;
思路3:“削苹果”
每次“削去”矩阵的第一层,然后将矩阵逆时针旋转 90 度,循环削去第一层;
而逆时针旋转的操作在 python 中可以用一行代码完成!
Last updated