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. 上面一行,从左到右,一定有
  2. 右边一列,从上到下,圈的行数大于1才有(避免重复上面一行的最后一个元素,行号从start+1开始)
  3. 下面一行,从右到左,圈的行数大于1且列数大于1的条件下,才有
  4. 左边一列,从下到上,圈的行数大于2且列数大于1的条件下,才有(避免重复上面一行的第一个元素,行号到start-1为止)

画图直观理解
2.7 剑指offer 顺时针打印矩阵

代码

# 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