云计算百科
云计算领域专业知识百科平台

LeetCode 566|重塑矩阵 Reshape the Matrix

LeetCode 566|重塑矩阵 Reshape the Matrix

费曼学习法核心思路:不用术语,用大白话讲清楚,假设你要讲给一个小白听懂;先明白问题本质,再思考方案,最后写代码,每行加详细注释

题目信息

题号:566
题目名称:重塑矩阵 Reshape the Matrix
难度:简单
标签:数组、矩阵、模拟

题目叙述

在 MATLAB 里面有个 reshape 函数,可以把一个 m × n 的二维矩阵,改成 r × c 的新矩阵,元素顺序保持不变。

现在给你二维矩阵 mat,还有两个正整数 r(目标行数)、c(目标列数)。
规则:

  • 按行优先遍历顺序(从上到下,每行从左向右)取出所有元素,依次填充到新矩阵;
  • 如果原矩阵总元素数量 m*n 不等于目标总元素数量 r*c,无法重塑,直接返回原矩阵;
  • 能重塑,返回新 r × c 矩阵。
  • 示例1

    输入:mat = [[1,2],[3,4]], r = 1, c = 4
    原矩阵是2行2列,总元素4个。目标1行4列,总数相等。
    行遍历顺序:1, 2, 3, 4
    输出:[[1,2,3,4]]

    示例2

    输入:mat = [[1,2],[3,4]], r = 2, c = 4
    原总数4,目标总数8,数量不匹配,不能重塑。
    输出:[[1,2],[3,4]]

    约束
    • m 和 n 的范围:1 <= m, n <= 100
    • r,c 都是正整数

    费曼讲解:破解思路(3种解法,从最简单到最优)

    费曼学习法:把复杂问题拆成普通人能听懂的比喻
    比喻:矩阵就像一盒排成多行多列的乒乓球。重塑=把所有乒乓球全部倒出来排成一条长队,再重新装到新盒子里。只有乒乓球总数一样,才能重装;总数不一样,不能重装,原样不动。

    核心数学知识点(本题灵魂)

    对于二维矩阵,行优先展开成一维序号 k(从0开始)

    • 原矩阵 m行n列:
      原行号:k // n (整数除法,向下取整)
      原列号:k % n (取余数)
    • 新矩阵 r行c列:
      新行号:k // c
      新列号:k % c

    举例子:原矩阵2行2列,k=2
    k//n = 2//2 =1 第1行;k%n=2%2=0 第0列 → mat[1][0]=3 ✔

    解法1:扁平化中转法(最容易理解,推荐新手)

    思路:

  • 先算原矩阵总元素,对比目标总数;不等直接返回原矩阵。
  • 遍历原矩阵,把所有元素拿出来放到一维扁平列表(乒乓球全部倒成长队)。
  • 新建空r行c列矩阵,循环依次从一维列表取元素填入。
  • Python代码(逐行最大注释)

    from typing import List

    class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) > List[List[int]]:
    # mat:输入二维矩阵;r目标行数;c目标列数;返回重塑后的二维矩阵
    # 第一步:获取原矩阵行数 m
    m = len(mat)
    # 获取原矩阵第0行的长度,也就是原矩阵列数 n
    n = len(mat[0])

    # 判断总元素数量是否相等,不等直接返回原矩阵,无法重塑
    if m * n != r * c:
    return mat

    # 创建一维扁平列表,用来存放所有元素(把矩阵摊平成一条线)
    flat_list = []
    # 外层循环:遍历原矩阵每一行
    for row in mat:
    # 内层循环:遍历当前行里面每一个数字
    for num in row:
    # 将数字追加到扁平一维列表尾部
    flat_list.append(num)

    # 创建最终结果二维列表
    result = []
    # 初始化一维列表的读取指针,从第0个元素开始读取
    ptr = 0
    # 循环r次,每次构建新矩阵的一行
    for i in range(r):
    # 临时单行列表,用来存放新矩阵当前行的c个元素
    temp_row = []
    # 循环c次,填充当前行每一列
    for j in range(c):
    # 取出扁平列表ptr位置元素,放到临时行
    temp_row.append(flat_list[ptr])
    # 指针向后移动一位,准备读取下一个元素
    ptr += 1
    # 把构建完成的单行,加入最终结果矩阵
    result.append(temp_row)

    # 返回重塑完成的矩阵
    return result

    费曼讲解解法1

    就像把盒子里所有乒乓球全部倒出来排成一队,然后拿新盒子,一行一行放进去。
    优点:逻辑直观,人脑好理解;缺点:多开了一个一维数组,额外占用内存。时间复杂度 O(m*n),要遍历全部元素。

    解法2:双循环遍历+坐标指针(原地填充,不摊平数组)

    思路:

  • 总数校验,总数不等返回原矩阵。
  • 创建r行c列,全部填充0的新矩阵。
  • 双循环遍历原矩阵每一个元素,用一个全局指针 k,不断+1。
  • 用 k//c 算出新矩阵行,k%c算出新矩阵列,直接赋值。
  • from typing import List

    class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) > List[List[int]]:
    # 获取原矩阵行数m
    m = len(mat)
    # 获取原矩阵列数n
    n = len(mat[0])

    # 元素总数不一致,无法重塑,返回原矩阵
    if m * n != r * c:
    return mat

    # 创建r行c列初始值全0的二维列表
    res = [[0] * c for _ in range(r)]
    # k是全局一维序号指针,从0开始计数
    k = 0

    # 外层循环遍历原矩阵每一行
    for i in range(m):
    # 内层循环遍历原矩阵当前行每一列
    for j in range(n):
    # 计算当前元素在新矩阵的行号:k整除c
    new_row = k // c
    # 计算当前元素在新矩阵的列号:k对c取余数
    new_col = k % c
    # 将原矩阵 mat[i][j] 的值,写入新矩阵对应位置
    res[new_row][new_col] = mat[i][j]
    # 序号+1,处理下一个元素
    k += 1

    return res

    费曼讲解解法2:不倒出乒乓球,一边读旧盒子,一边往新盒子里面放,只需要一个计数器标记这是第几个球。节省了一维数组空间。

    解法3:数学索引映射最优单循环(推荐面试写)

    最优写法:只用一层循环,直接用一维序号k同时映射原矩阵坐标、新矩阵坐标,代码最简洁。面试首选。

    from typing import List

    class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) > List[List[int]]:
    # m:原矩阵行数
    m = len(mat)
    # n:原矩阵列数
    n = len(mat[0])

    # 总数校验,数量不一致直接返回原矩阵
    if m * n != r * c:
    return mat

    # 初始化r行c列全0矩阵
    res = [[0] * c for _ in range(r)]

    # 一维序号k从0遍历到总元素mn-1,一层循环搞定
    for k in range(m * n):
    # 原矩阵行:k除以原列数n,整数除法
    old_row = k // n
    # 原矩阵列:k对原列数n取模
    old_col = k % n

    # 新矩阵行:k除以目标列数c,整数除法
    new_row = k // c
    # 新矩阵列:k对目标列数c取模
    new_col = k % c

    # 元素拷贝
    res[new_row][new_col] = mat[old_row][old_col]

    return res

    费曼讲解解法3:
    想象所有乒乓球编号0、1、2、3……。不管旧盒子还是新盒子,同一个编号的球,都可以通过「整除行数、取余列数」算出它在盒子里的位置。不需要两层循环,一个循环就能完成映射。
    时间复杂度 O(mn),空间 O(r*c)(输出矩阵必须占用,不算额外开销)。


    应用场景举例

  • 图像处理:图像本质是二维像素矩阵。深度学习模型经常需要把图片矩阵重塑(reshape),比如把 28×28 的灰度图重塑成 1×784 的一维向量,送入神经网络。
  • 数据分析:Pandas / Numpy 中 reshape,表格数据维度转换。比如采集数据是多行多列,需要改成一行向量做特征输入。
  • 传感器数据:设备采集10行10列传感器数据,需要改成5行20列矩阵,方便绘图展示。
  • 游戏开发:地图网格矩阵重塑,把小地图二维网格重新排布。
  • 这个LeetCode题目本质就是复刻 Numpy / MATLAB 的 reshape 底层逻辑。

    测试代码(直接运行验证)

    # 测试样例1
    sol = Solution()
    mat1 = [[1,2],[3,4]]
    print(sol.matrixReshape(mat1, 1, 4)) # [[1,2,3,4]]

    # 测试样例2
    print(sol.matrixReshape(mat1,2,4)) # [[1,2],[3,4]]

    费曼自检(你能不能讲出来?)

  • 什么时候不能重塑?✅ 元素总数不一样
  • k//n 和 k%n 分别代表什么?✅ 行号、列号
  • 三种方案优缺点?✅ 摊平法好懂;双循环省空间;单循环代码简洁面试首选
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » LeetCode 566|重塑矩阵 Reshape the Matrix
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!