螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

代码

不断地剥离矩阵的外层,将其元素按顺时针顺序添加到结果列表中,直到矩阵为空。

def spiralOrder(matrix):
    if not matrix:
        return []

    result = []
    while matrix:
        # 取出第一行
        result += matrix.pop(0)
        
        # 取出每一列的最后一个元素
        if matrix and matrix[0]:
            for row in matrix:
                result.append(row.pop())
        
        # 取出最后一行的逆序
        if matrix:
            result += matrix.pop()[::-1]
        
        # 取出每一列的第一个元素的逆序
        if matrix and matrix[0]:
            for row in matrix[::-1]:
                result.append(row.pop(0))

    return result

一行代码递归操作

def spiralOrder(self, matrix):
    return matrix and [*matrix.pop(0)] + self.spiralOrder([*zip(*matrix)][::-1])

解释

  1. 基础检查(matrix and

    • matrix and ... 的作用是检查 matrix 是否为空。如果 matrix 为空,matrix and ... 将返回 False,递归停止。
    • 如果 matrix 非空,则继续执行后面的操作。
  2. 取出第一行([*matrix.pop(0)]

    • matrix.pop(0) 从矩阵 matrix 中取出第一行,并将其从 matrix 中移除。
    • [...matrix.pop(0)] 使用解包操作符 * 将第一行的元素逐个展开成单个元素,并放入列表中。
  3. 递归调用(self.spiralOrder(...)))

    • [ *zip(*matrix) ] 使用 zip(*matrix)matrix 进行转置操作。转置操作将行变为列,列变为行。
    • [::-1] 旋转转置后的矩阵,即将其上下颠倒。
    • self.spiralOrder(...) 递归调用 spiralOrder 函数,传入转置并颠倒后的矩阵。
  4. 组合结果(+

    • 通过 + 运算符将当前取出的第一行与递归调用的结果拼接在一起。

具体步骤

假设 matrix 是如下矩阵:

matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]
]
  1. 第一次递归调用

    • 取出第一行 [1, 2, 3, 4]
    • 剩余矩阵为:
      [
          [5, 6, 7, 8],
          [9, 10, 11, 12],
          [13, 14, 15, 16]
      ]
      
    • 转置并颠倒后:
      [
          [8, 12, 16],
          [7, 11, 15],
          [6, 10, 14],
          [5, 9, 13]
      ]
      
  2. 第二次递归调用

    • 取出第一行 [8, 12, 16]
    • 剩余矩阵为:
      [
          [7, 11, 15],
          [6, 10, 14],
          [5, 9, 13]
      ]
      
    • 转置并颠倒后:
      [
          [15, 14, 13],
          [11, 10, 9],
          [7, 6, 5]
      ]
      
  3. 继续递归

    • 递归调用继续,直到矩阵为空。

最终结果

通过不断地取出第一行,然后转置并颠倒剩余矩阵,再递归处理,最终将所有元素按螺旋顺序输出。

关键点

  • matrix and 确保递归在矩阵为空时停止。
  • matrix.pop(0) 提取并移除第一行。
  • zip(*matrix) 转置矩阵。
  • [::-1] 颠倒矩阵。
  • 递归合并结果。

这一行代码巧妙地结合了矩阵操作和递归,简洁地实现了螺旋矩阵的顺时针输出。

详细解释 zip(*matrix) 对矩阵的转置操作

当然,使用 zip(*matrix) 来对矩阵进行转置是 Python 中一个非常简洁且高效的方法。让我们详细解释这一过程。

什么是矩阵转置?

矩阵转置的操作是将矩阵的行和列互换。例如,如果有一个矩阵:

1 2 3
4 5 6
7 8 9

转置后的矩阵将变成:

1 4 7
2 5 8
3 6 9

zip(*matrix) 是如何实现转置的?

zip(*matrix) 利用了 Python 中的 zip 函数和解包操作符 * 来实现矩阵的转置。

步骤解析:

  1. 解包操作符 *

    • 在函数调用时,*matrix 会将矩阵中的每一行作为单独的参数传递给 zip 函数。
  2. zip 函数

    • zip 函数可以将多个可迭代对象作为参数,并返回一个迭代器,该迭代器会生成由这些可迭代对象中的元素组成的元组。
    • 具体来说,zip 函数会将输入的第一个元素组合成一个元组,第二个元素组合成一个元组,依此类推。

具体例子:

假设我们有以下矩阵 matrix

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

当我们执行 zip(*matrix) 时,会发生以下步骤:

  1. 解包矩阵

    • *matrix 将矩阵解包成单独的行:
      zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
      
  2. zip 函数处理

    • zip 函数将对应位置的元素组合成元组:
      • 第一个位置的元素组合: (1, 4, 7)
      • 第二个位置的元素组合: (2, 5, 8)
      • 第三个位置的元素组合: (3, 6, 9)
    • 结果是一个包含这些元组的迭代器。
  3. 转换为列表

    • 如果你需要将结果转换为列表,可以用 list 函数:
      transposed_matrix = list(zip(*matrix))
      
    • transposed_matrix 的内容将是:
      [
          (1, 4, 7),
          (2, 5, 8),
          (3, 6, 9)
      ]
      

代码示例:

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

transposed_matrix = list(zip(*matrix))
print(transposed_matrix)

输出将是:

[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

进一步转换:

如果你希望最终的转置矩阵仍然是列表的列表形式,而不是元组的列表,可以进一步将元组转换为列表:

transposed_matrix = [list(row) for row in zip(*matrix)]
print(transposed_matrix)

输出将是:

[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

总结

  • *matrix 将矩阵中的每一行解包成单独的参数。
  • zip 函数将这些行的对应元素组合成新的元组,从而实现了行列互换,即矩阵转置。
  • 通过将结果转换为列表,可以得到最终的转置矩阵。

这种方法非常简洁高效,尤其适合在 Python 中进行矩阵操作。

使用python对矩阵进行逆时针旋转

逆时针旋转矩阵是一个常见的操作,可以通过多种方法实现。我们将详细介绍一种简单且高效的方法,使用 Python 的列表推导和 zip 函数来实现。

方法解释

假设我们有一个矩阵 matrix,要将其逆时针旋转 90 度。我们可以分两步完成这个操作:

  1. 转置矩阵:将矩阵的行和列互换。
  2. 翻转行顺序:将转置后的矩阵的每一行按照从下到上的顺序翻转。

示例代码

让我们用具体的代码示例来说明这个过程:

def rotate_matrix_anticlockwise(matrix):
    # Step 1: Transpose the matrix using zip and unpacking
    transposed_matrix = list(zip(*matrix))
    
    # Step 2: Reverse the order of rows in the transposed matrix
    rotated_matrix = transposed_matrix[::-1]
    
    # Convert tuples to lists (optional, depending on your needs)
    rotated_matrix = [list(row) for row in rotated_matrix]
    
    return rotated_matrix

# Example usage
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

rotated_matrix = rotate_matrix_anticlockwise(matrix)
for row in rotated_matrix:
    print(row)

输出结果

运行上述代码,输出将是:

[3, 6, 9]
[2, 5, 8]
[1, 4, 7]

分步解释

  1. 转置矩阵

    • 使用 zip(*matrix) 对矩阵进行转置。转置后的矩阵是:
      [(1, 4, 7),
       (2, 5, 8),
       (3, 6, 9)]
      
  2. 翻转行顺序

    • 使用 [::-1] 翻转行的顺序。翻转后的矩阵是:
      [(3, 6, 9),
       (2, 5, 8),
       (1, 4, 7)]
      
  3. 转换为列表(可选):

    • 将每一行的元组转换为列表,得到最终结果:
      [[3, 6, 9],
       [2, 5, 8],
       [1, 4, 7]]
      

总结

通过简单的两步操作:转置矩阵和翻转行顺序,我们可以高效地实现矩阵的逆时针旋转。这个方法利用了 Python 强大的内置函数和列表推导,代码简洁且易于理解。

如果是顺时针旋转90度呢

顺时针旋转矩阵 90 度同样可以通过类似的方法来实现。和逆时针旋转一样,我们可以将这个操作拆分成两步:

  1. 转置矩阵:将矩阵的行和列互换。
  2. 翻转列顺序:将转置后的矩阵的每一列按照从左到右的顺序翻转。

示例代码

以下是实现顺时针旋转矩阵 90 度的 Python 代码:

def rotate_matrix_clockwise(matrix):
    # Step 1: Transpose the matrix using zip and unpacking
    transposed_matrix = list(zip(*matrix))
    
    # Step 2: Reverse the order of columns in the transposed matrix
    rotated_matrix = [list(row)[::-1] for row in transposed_matrix]
    
    return rotated_matrix

# Example usage
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

rotated_matrix = rotate_matrix_clockwise(matrix)
for row in rotated_matrix:
    print(row)

输出结果

运行上述代码,输出将是:

[7, 4, 1]
[8, 5, 2]
[9, 6, 3]

分步解释

  1. 转置矩阵

    • 使用 zip(*matrix) 对矩阵进行转置。转置后的矩阵是:
      [(1, 4, 7),
       (2, 5, 8),
       (3, 6, 9)]
      
  2. 翻转列顺序

    • 使用列表推导和 [::-1] 翻转每一行的顺序。翻转后的矩阵是:
      [[7, 4, 1],
       [8, 5, 2],
       [9, 6, 3]]
      

代码总结

通过简单的两步操作:转置矩阵和翻转列顺序,我们可以高效地实现矩阵的顺时针旋转。这个方法利用了 Python 强大的内置函数和列表推导,代码简洁且易于理解。这种方法不仅易于实现,而且非常高效,适用于各种矩阵旋转需求。

如何按照对角线输出矩阵的值?

要按照对角线输出矩阵的值,我们可以遵循以下步骤。对角线遍历的顺序是从左上角开始,依次输出每一条对角线的元素。具体来说,我们从第一行的第一个元素开始,输出每一条对角线,直到遍历完整个矩阵。

我们可以通过两次循环来实现这一点:

  1. 从矩阵的第一行开始,逐渐右移起点,直到到达最后一列的第一个元素。
  2. 从第二行的第一个元素开始,逐渐下移起点,直到到达最后一行。

示例代码

以下是 Python 代码来实现这一目标:

def diagonal_traverse(matrix):
    if not matrix or not matrix[0]:
        return []
    
    rows = len(matrix)
    cols = len(matrix[0])
    result = []

    # Traverse from the first row
    for col in range(cols):
        i, j = 0, col
        diagonal = []
        while i < rows and j >= 0:
            diagonal.append(matrix[i][j])
            i += 1
            j -= 1
        result.append(diagonal)
    
    # Traverse from the first column (starting from the second element)
    for row in range(1, rows):
        i, j = row, cols - 1
        diagonal = []
        while i < rows and j >= 0:
            diagonal.append(matrix[i][j])
            i += 1
            j -= 1
        result.append(diagonal)
    
    return result

# Example usage
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

diagonals = diagonal_traverse(matrix)
for diagonal in diagonals:
    print(diagonal)

输出结果

运行上述代码,输出将是:

[1]
[2, 4]
[3, 5, 7]
[6, 8]
[9]

解释

  1. 从第一行开始遍历

    • 起点从 (0, 0)(0, n-1)
    • 在每个起点 (0, col),沿着对角线方向遍历,直到到达矩阵边界。
  2. 从第一列开始遍历(从第二个元素开始):

    • 起点从 (1, 0)(m-1, 0)
    • 在每个起点 (row, n-1),沿着对角线方向遍历,直到到达矩阵边界。