剑指 Offer 29. 顺时针打印矩阵
一、题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
原题链接:顺时针打印矩阵
二、问题分析
输入:
0 1 2 3 4
5 6 7 8 9
0 1 2 3 4
5 6 7 8 9
输出:
第一轮输出:0 1 2 3 4 9 4 9 8 7 6 5 0 5,矩阵变成了
6 7 8
1 2 3
第二轮输出:6 7 8 3 2 1,完毕。
因此,输出最外层后,里面形成一个新的矩阵。
问题是:在代码中,如何定义新矩阵的边界呢?
定义上、下、左、右四个边界值,初始值分别为 0、matrix.length、0、matrix[i].length
每次输出对应的行/列的数据后,边界值就减一
当边界之间发送重复时,说明已经输出所有值了
三、数据结构及算法分析
1.数据结构
输入格式:List[ List[ int ] ]
输出格式:List[ int ]
因此,
定义四个整型值,代表上下左右四个边界;
定义一个 res 数组,将每次输出的值添加到数组末尾。
2.涉及算法
输出最外层的数据算法:
从左到右、从上到下、从右到左、从下到上
根据上、下、左、右边界值实现上述过程。
代码实现如下:
while True:
for j in range(left, right + 1):
res.append(matrix[top][j])
top += 1
if top > bottom: break
for i in range(top, bottom + 1):
res.append(matrix[i][right])
right -= 1
if right < left: break
for j in range(right, left - 1, -1):
res.append(matrix[bottom][j])
bottom -= 1
if bottom < top: break
for i in range(bottom, top - 1, -1):
res.append(matrix[i][left])
left += 1
if left > right: break
时间复杂度:O(M * N),其中M、N为矩阵的行数和列数
空间复杂度:O(1)
四、总结
解题方法为模拟法
通过分析实际输出过程中的规律,建立输出模型。
难点:通过四个边界,来规定输出顺序以及判定输出是否结束。
五、完整源码
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if len(matrix) == 0:
return []
top, bottom, left, right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
res = []
while True:
for j in range(left, right + 1):
res.append(matrix[top][j])
top += 1
if top > bottom: break
for i in range(top, bottom + 1):
res.append(matrix[i][right])
right -= 1
if right < left: break
for j in range(right, left - 1, -1):
res.append(matrix[bottom][j])
bottom -= 1
if bottom < top: break
for i in range(bottom, top - 1, -1):
res.append(matrix[i][left])
left += 1
if left > right: break
return res
时间复杂度:O(M * N),其中M、N为矩阵的行数和列数
空间复杂度:O(1)
一 起 前 进 |