力扣刷题之 顺时针打印矩阵

剑指 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)


一 起 前 进
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值