重塑矩阵

标签: 数组 矩阵 模拟

难度: Easy

在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 rc ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例 1:

输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]

示例 2:

输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 100
  • -1000 <= mat[i][j] <= 1000
  • 1 <= r, c <= 300

Submission

运行时间: 23 ms

内存: 16.8 MB

from typing import List

class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
        m, n = len(mat), len(mat[0])
        if m * n != r * c:
            return mat
        
        nums = [num for row in mat for num in row]
        reshaped_mat = []
        for i in range(0, r * c, c):
            reshaped_mat.append(nums[i:i+c])
        
        return reshaped_mat

Explain

这个题解的思路是先将二维矩阵 mat 转换为一维数组 nums,然后再根据给定的行数 r 和列数 c 将一维数组重塑为新的二维矩阵。具体步骤如下: 1. 首先判断原始矩阵的元素总数是否等于重塑后矩阵的元素总数,如果不相等则直接返回原始矩阵。 2. 使用列表推导式将二维矩阵 mat 转换为一维数组 nums。 3. 创建一个空列表 reshaped_mat 用于存储重塑后的矩阵。 4. 使用循环从 nums 中按照列数 c 取出元素,每 c 个元素作为一行添加到 reshaped_mat 中。 5. 返回重塑后的矩阵 reshaped_mat。

时间复杂度: O(m*n)

空间复杂度: O(m*n)

```python
from typing import List

class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
        m, n = len(mat), len(mat[0])
        # 判断原始矩阵的元素总数是否等于重塑后矩阵的元素总数
        if m * n != r * c:
            return mat
        
        # 将二维矩阵转换为一维数组
        nums = [num for row in mat for num in row]
        # 创建重塑后的矩阵
        reshaped_mat = []
        # 按照列数 c 取出元素,每 c 个元素作为一行添加到重塑后的矩阵中
        for i in range(0, r * c, c):
            reshaped_mat.append(nums[i:i+c])
        
        return reshaped_mat
```

Explore

在提供的算法中,首先会计算 mat 的行数 m 和列数 n。如果 mat 是空的,即不存在任何元素,m 和 n 将都为零。算法首先检查 m*n 是否等于 r*c,如果不等于,则直接返回原矩阵 mat。对于空的 mat,由于没有元素,m*n 为 0,除非 r 和 c 被设置为 0,否则不会进行重塑。如果 mat 包含空的子数组,即某些行是空的,这些空行在计算 m 和 n 时会被视为有效行,但不包含任何元素,算法仍然工作正常,只要总元素数正确。

算法确实将二维矩阵转换为一维数组作为重塑过程的中间步骤,这涉及一定的时间和空间复杂度。对于非常大的矩阵,这个转换操作需要遍历所有元素,因此时间复杂度为 O(m*n),同时也需要相同的额外空间来存储这些元素。尽管这可能导致性能损耗,特别是在空间使用上,但是这样的处理简化了代码的逻辑。如果性能是关键考虑因素,可以考虑直接在原矩阵上操作,避免额外的空间分配。

根据题解的算法逻辑,即使 r 和 c 都为 1,输出仍然是一个二维数组,只不过这个数组只包含一个子数组,该子数组恰好包含所有原始矩阵元素。Python 中的列表推导式和数组分割操作保证了即使是 r=1 和 c=1,输出格式仍然是二维的。这与 Python 的列表处理方式和题目要求输出为二维矩阵的规范一致。

在重塑矩阵的过程中,新矩阵的每一行都应包含 c 个元素。因此,从一维数组 nums 中抽取元素填充新矩阵时,每次应取出 c 个元素作为一行。循环中的步长 c 确保了每次迭代从前一个行分割点跳过 c 个元素,恰好取到下一个行的起始位置。这是一个高效的方式,确保每个新行正确地从一维数组中截取对应的元素数量,符合新矩阵的列数要求。