2.7 剑指offer 顺时针打印矩阵
题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
思路
从外到里,按圈划分,打印矩阵。起始点是(0,0)[(i,i)],循环到最内圈,找规律,发现满足 行数和列数大于2i,即有圈可以遍历。
遍历圈,
- 上面一行,从左到右,一定有
- 右边一列,从上到下,圈的行数大于1才有(避免重复上面一行的最后一个元素,行号从start+1开始)
- 下面一行,从右到左,圈的行数大于1且列数大于1的条件下,才有
- 左边一列,从下到上,圈的行数大于2且列数大于1的条件下,才有(避免重复上面一行的第一个元素,行号到start-1为止)
画图直观理解
代码
# matrix类型为二维列表,需要返回列表
def printMatrix(matrix):
if len(matrix) == 0 or len(matrix[0]) == 0:
return matrix
cols = len(matrix[0])
rows = len(matrix)
start = 0
ans = []
while cols > 2 * start and rows > 2 * start:
temp = []
temp = (PrintCircle(matrix, rows, cols, start))
for i in temp:
ans.append(i)
start += 1
return ans
def PrintCircle(matrix, rows, cols, start):
ans =[]
# 圈(遍历)的终止行和列
endrow = rows - start - 1
endcol = cols - start -1
# 从左到右,上面一行
for i in range(start, endcol + 1):
ans.append(matrix[start][i])
# 从上到下,右边一列
if endrow > start:
for i in range(start + 1, endrow + 1):
ans.append(matrix[i][endcol])
# 从右到左,下面一行
if endcol > start and endrow > start:
for i in range(endcol - 1, start-1, -1):
ans.append(matrix[endrow][i])
# 从下到上,左边一列
if endcol > start and endrow > start + 1:
for i in range(endrow - 1, start, -1):
ans.append(matrix[i][start])
return ans