螺旋遍历和生成矩阵

class Matrix:
    @staticmethod
    def spiral_matrix(matrix: list) -> list:
        """
        顺时针螺旋遍历矩阵
        :param matrix: 矩阵,二维列表
        :return: 遍历结果,一维列表
        """
        if not matrix:
            return
        m, n = len(matrix), len(matrix[0])
        try:
            for i in range(m):
                assert len(matrix[i]) == n
        except AssertionError:
            raise
        res, left, right, up, down = [], 0, n - 1, 0, m - 1
        # res长度 == m * n 则遍历结束
        while len(res) < m * n:
            # 从左向右遍历
            if up <= down:
                for j in range(left, right + 1):
                    res.append(matrix[up][j])
                up += 1
            # 从上向下遍历
            if left <= right:
                for i in range(up, down + 1):
                    res.append(matrix[i][right])
                right -= 1
            # 从右向左遍历
            if up <= down:
                for j in range(right, left-1, -1):
                    res.append(matrix[down][j])
                down -= 1
            # 从下向上遍历
            if left <= right:
                for i in range(down, up - 1, -1):
                    res.append(matrix[i][left])
                left += 1
        return res

    @staticmethod
    def generate_matrix(m: int, n: int) -> list:
        """
        顺时针生成m*n矩阵,包含元素 1 ~ m*n 所有元素
        :param m: 矩阵行
        :param n: 矩阵列
        :return:  矩阵,二维列表
        """
        if m <= 0 or n <= 0:
            return
        # 不能用 [[None] * n] * m 初始化  这种方式每行是引用的同一地址空间,修改列会影响所有行
        res = [[None for _ in range(n)] for _ in range(m)]
        left, right, up, down = 0, n - 1, 0, m - 1
        num = 1
        while num <= m * n:
            # 从左向右遍历
            if up <= down:
                for j in range(left, right + 1):
                    res[up][j] = num
                    num += 1
                up += 1
            # 从上向下遍历
            if left <= right:
                for i in range(up, down + 1):
                    res[i][right] = num
                    num += 1
                right -= 1
            # 从右向左遍历
            if up <= down:
                for j in range(right, left - 1, -1):
                    res[down][j] = num
                    num += 1
                down -= 1
            # 从下向上遍历
            if left <= right:
                for i in range(down, up - 1, -1):
                    res[i][left] = num
                    num += 1
                left += 1
        return res


if __name__ == '__main__':
    mt = Matrix()
    matrix_1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19, 20]]
    print(mt.spiral_matrix(matrix_1))
    matrix_2 = mt.generate_matrix(5, 4)
    print(matrix_2)
    print(mt.spiral_matrix(matrix_2))

初始化矩阵:不能用[[None] * n] * m方式

实验:

res1 = [[None for _ in range(3)] for _ in range(2)]
for i in range(len(res1)):
    print('{}方式:第{}行地址为{}'.format('[[None for _ in range(3)] for _ in range(2)]', i, id(res1[i])))

print('-----------------')
res2 = [[None] * 3] * 2
for i in range(len(res2)):
    print('{}方式:第{}行地址为{}'.format('[[None] * 3] * 2', i, id(res2[i])))

输出:

[[None for _ in range(3)] for _ in range(2)]方式:第0行地址为4082224
[[None for _ in range(3)] for _ in range(2)]方式:第1行地址为14209192
-----------------
[[None] * 3] * 2方式:第0行地址为14209072
[[None] * 3] * 2方式:第1行地址为14209072

优化循环条件


class Matrix:
    @staticmethod
    def spiral_matrix(matrix: list) -> list:
        """
        顺时针螺旋遍历矩阵
        :param matrix: 矩阵,二维列表
        :return: 遍历结果,一维列表
        """
        if not matrix:
            return
        m, n = len(matrix), len(matrix[0])
        try:
            for i in range(m):
                assert len(matrix[i]) == n
        except AssertionError:
            raise
        res, left, right, up, down = list(), 0, n - 1, 0, m - 1
        # 按层模拟遍历(一层一层剥离)
        while left <= right and up <= down:
            # 从左向右遍历up行
            for j in range(left, right + 1):
                res.append(matrix[up][j])
            # 从上向下遍历right列
            for i in range(up + 1, down + 1):
                res.append(matrix[i][right])
            if left < right and up < down:
                # 从右向左遍历down行
                for j in range(right - 1, left - 1, -1):
                    res.append(matrix[down][j])
                # 从下向上遍历left列
                for i in range(down - 1, up, -1):
                    res.append(matrix[i][left])
            left, right, up, down = left + 1, right - 1, up + 1, down - 1
        return res

    @staticmethod
    def generate_matrix(m: int, n: int) -> list:
        """
        顺时针生成m*n矩阵,包含元素 1 ~ m*n 所有元素
        :param m: 矩阵行
        :param n: 矩阵列
        :return:  矩阵,二维列表
        """
        if m <= 0 or n <= 0:
            return
        # 不能用 [[None] * n] * m 初始化  这种方式每行是引用的同一地址空间,修改列会影响所有行
        res = [[None for _ in range(n)] for _ in range(m)]
        left, right, up, down = 0, n - 1, 0, m - 1
        num = 1
        while left <= right and up <= down:
            # 从左向右遍历up行
            for j in range(left, right + 1):
                res[up][j] = num
                num += 1
            # 从上向下遍历right列
            for i in range(up + 1, down + 1):
                res[i][right] = num
                num += 1
            if left < right and up < down:
                # 从右向左遍历down行
                for j in range(right - 1, left - 1, -1):
                    res[down][j] = num
                    num += 1
                # 从下向上遍历left列
                for i in range(down - 1, up, -1):
                    res[i][left] = num
                    num += 1
            left, right, up, down = left + 1, right - 1, up + 1, down - 1
        return res

posted @ 2022-06-17 10:20  daxiacet  阅读(50)  评论(0编辑  收藏  举报