剑指 Offer 29. 顺时针打印矩阵

47 阅读1分钟

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 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: 模拟+边界设定

设定上下左右4个边界 和 上下左右4个遍历方向, 每次遍历时根据当前的遍历方向和对应边界进行判断, 并且进行方向/边界调整

示例代码1:

def spiralOrder(self, matrix: [[int]]) -> [int]:
    if not matrix:
        return []

    # 边界
    top = 1
    left = 0
    right = len(matrix[0]) - 1
    bottom = len(matrix) - 1

    total = (right + 1) * (bottom + 1)
    res = [0] * total

    i = j = 0
    # direc方向 1:右  2:下  3:左  4:上
    direc = 1
    for x in range(total):
        print(i, j, matrix[i][j])
        res[x] = matrix[i][j]
        if direc == 1:
            if j >= right:
                direc = 2
                right -= 1
            else:
                j += 1

        if direc == 2:
            if i >= bottom:
                direc = 3
                bottom -= 1
            else:
                i += 1

        if direc == 3:
            if j <= left:
                direc = 4
                left += 1
            else:
                j -= 1

        if direc == 4:
            if i <= top:
                direc = 1
                top += 1
                j += 1
            else:
                i -= 1

    return res

解题思路2: 删除顶行+旋转

我们直接将数组的第一行删除(相当于便利过), 然后将数组向左旋转90°, 再次删除, 直到循环结束

def spiralOrder2(self, matrix: [[int]]) -> [int]:
    res = []
    while matrix:
        res += matrix.pop(0)
        matrix = list(zip(*matrix))[::-1]
    return res

zip() 函数可以将2个一维数组打包为一个元组. 打包的元组是一个对象, 可以用list来转成数组
如: a = [1,2,3], b = [4,5,6], list(zip(a, b)) = [(1, 4), (2, 5), (3, 6)]

zip(*) 函数是将元组还原成二维数组
a = [[5, 6, 7], [9, 10, 11]], list(zip(*a)) = [ (5, 9), (6, 10), (7, 11) ]