给你一个 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])
解释
基础检查(
matrix and
):matrix and ...
的作用是检查matrix
是否为空。如果matrix
为空,matrix and ...
将返回False
,递归停止。- 如果
matrix
非空,则继续执行后面的操作。
取出第一行(
[*matrix.pop(0)]
):matrix.pop(0)
从矩阵matrix
中取出第一行,并将其从matrix
中移除。[...matrix.pop(0)]
使用解包操作符*
将第一行的元素逐个展开成单个元素,并放入列表中。
递归调用(
self.spiralOrder(...)
)):[ *zip(*matrix) ]
使用zip(*matrix)
对matrix
进行转置操作。转置操作将行变为列,列变为行。[::-1]
旋转转置后的矩阵,即将其上下颠倒。self.spiralOrder(...)
递归调用spiralOrder
函数,传入转置并颠倒后的矩阵。
组合结果(
+
):- 通过
+
运算符将当前取出的第一行与递归调用的结果拼接在一起。
- 通过
具体步骤
假设 matrix
是如下矩阵:
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]
]
第一次递归调用:
- 取出第一行
[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] ]
- 取出第一行
第二次递归调用:
- 取出第一行
[8, 12, 16]
。 - 剩余矩阵为:
[ [7, 11, 15], [6, 10, 14], [5, 9, 13] ]
- 转置并颠倒后:
[ [15, 14, 13], [11, 10, 9], [7, 6, 5] ]
- 取出第一行
继续递归:
- 递归调用继续,直到矩阵为空。
最终结果
通过不断地取出第一行,然后转置并颠倒剩余矩阵,再递归处理,最终将所有元素按螺旋顺序输出。
关键点
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
函数和解包操作符 *
来实现矩阵的转置。
步骤解析:
解包操作符
*
:- 在函数调用时,
*matrix
会将矩阵中的每一行作为单独的参数传递给zip
函数。
- 在函数调用时,
zip
函数:zip
函数可以将多个可迭代对象作为参数,并返回一个迭代器,该迭代器会生成由这些可迭代对象中的元素组成的元组。- 具体来说,
zip
函数会将输入的第一个元素组合成一个元组,第二个元素组合成一个元组,依此类推。
具体例子:
假设我们有以下矩阵 matrix
:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
当我们执行 zip(*matrix)
时,会发生以下步骤:
解包矩阵:
*matrix
将矩阵解包成单独的行:zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
zip
函数处理:zip
函数将对应位置的元素组合成元组:- 第一个位置的元素组合:
(1, 4, 7)
- 第二个位置的元素组合:
(2, 5, 8)
- 第三个位置的元素组合:
(3, 6, 9)
- 第一个位置的元素组合:
- 结果是一个包含这些元组的迭代器。
转换为列表:
- 如果你需要将结果转换为列表,可以用
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 度。我们可以分两步完成这个操作:
- 转置矩阵:将矩阵的行和列互换。
- 翻转行顺序:将转置后的矩阵的每一行按照从下到上的顺序翻转。
示例代码
让我们用具体的代码示例来说明这个过程:
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]
分步解释
转置矩阵:
- 使用
zip(*matrix)
对矩阵进行转置。转置后的矩阵是:[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
- 使用
翻转行顺序:
- 使用
[::-1]
翻转行的顺序。翻转后的矩阵是:[(3, 6, 9), (2, 5, 8), (1, 4, 7)]
- 使用
转换为列表(可选):
- 将每一行的元组转换为列表,得到最终结果:
[[3, 6, 9], [2, 5, 8], [1, 4, 7]]
- 将每一行的元组转换为列表,得到最终结果:
总结
通过简单的两步操作:转置矩阵和翻转行顺序,我们可以高效地实现矩阵的逆时针旋转。这个方法利用了 Python 强大的内置函数和列表推导,代码简洁且易于理解。
如果是顺时针旋转90度呢
顺时针旋转矩阵 90 度同样可以通过类似的方法来实现。和逆时针旋转一样,我们可以将这个操作拆分成两步:
- 转置矩阵:将矩阵的行和列互换。
- 翻转列顺序:将转置后的矩阵的每一列按照从左到右的顺序翻转。
示例代码
以下是实现顺时针旋转矩阵 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]
分步解释
转置矩阵:
- 使用
zip(*matrix)
对矩阵进行转置。转置后的矩阵是:[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
- 使用
翻转列顺序:
- 使用列表推导和
[::-1]
翻转每一行的顺序。翻转后的矩阵是:[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
- 使用列表推导和
代码总结
通过简单的两步操作:转置矩阵和翻转列顺序,我们可以高效地实现矩阵的顺时针旋转。这个方法利用了 Python 强大的内置函数和列表推导,代码简洁且易于理解。这种方法不仅易于实现,而且非常高效,适用于各种矩阵旋转需求。
如何按照对角线输出矩阵的值?
要按照对角线输出矩阵的值,我们可以遵循以下步骤。对角线遍历的顺序是从左上角开始,依次输出每一条对角线的元素。具体来说,我们从第一行的第一个元素开始,输出每一条对角线,直到遍历完整个矩阵。
我们可以通过两次循环来实现这一点:
- 从矩阵的第一行开始,逐渐右移起点,直到到达最后一列的第一个元素。
- 从第二行的第一个元素开始,逐渐下移起点,直到到达最后一行。
示例代码
以下是 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]
解释
从第一行开始遍历:
- 起点从
(0, 0)
到(0, n-1)
。 - 在每个起点
(0, col)
,沿着对角线方向遍历,直到到达矩阵边界。
- 起点从
从第一列开始遍历(从第二个元素开始):
- 起点从
(1, 0)
到(m-1, 0)
。 - 在每个起点
(row, n-1)
,沿着对角线方向遍历,直到到达矩阵边界。
- 起点从