☰
LeetCode 1727:矩阵重排与最大全1子矩阵解法
2026/11/3 3:42:01 网站建设 项目流程

1. 题目解析与问题重述

今天我们来拆解一道来自LeetCode的矩阵操作题目——1727. 重新排列后的最大子矩阵。这道题在2023年1月的周赛中首次出现,属于中等难度,但实际考察的是对矩阵预处理和贪心算法的综合运用能力。

题目描述如下: 给定一个二进制矩阵matrix,你可以任意重新排列矩阵的每一列。在重新排列后,找到仅由1组成的最大子矩阵,并返回其面积。

示例: 输入:matrix = [[0,0,1],[1,1,1],[1,0,1]] 输出:4 解释:可以重新排列列得到 [[1,0,0],[1,1,1],[1,1,0]],此时最大全1子矩阵是右下角的2×2矩阵,面积为4。

2. 解题思路与核心算法

2.1 暴力法的局限性

最直观的想法是尝试所有可能的列排列组合,然后对每种排列计算最大全1子矩阵。但这种方法的时间复杂度是O(m!×m×n),对于m=100的矩阵来说完全不可行。

2.2 关键观察点

这道题的核心在于发现两个重要性质:

  1. 列的重排列不会改变每列的1的数量
  2. 最大全1子矩阵的高度取决于连续的1的列

2.3 预处理技巧

我们需要先对矩阵进行预处理,计算每个位置上方连续的1的个数(包括自己)。这可以通过动态规划实现:

for i in range(1, rows): for j in range(cols): if matrix[i][j] == 1: matrix[i][j] += matrix[i-1][j]

预处理后的矩阵称为"高度矩阵",它记录了每个位置上方连续的1的层数。

2.4 贪心策略的应用

对于每一行,我们可以:

  1. 获取当前行的高度数组
  2. 将高度数组降序排序
  3. 计算可能的最大矩形面积:max_area = max(max_area, heights[i]*(i+1))

这个策略之所以有效,是因为排序后,当前高度能保持的宽度就是其索引+1。

3. 完整代码实现与逐行解析

def largestSubmatrix(matrix): if not matrix or not matrix[0]: return 0 rows, cols = len(matrix), len(matrix[0]) # 预处理计算高度 for i in range(1, rows): for j in range(cols): if matrix[i][j] == 1: matrix[i][j] += matrix[i-1][j] max_area = 0 # 逐行处理 for i in range(rows): # 获取当前行的高度并排序 row = sorted(matrix[i], reverse=True) # 计算可能的最大面积 for j in range(cols): if row[j] == 0: break current_area = row[j] * (j + 1) if current_area > max_area: max_area = current_area return max_area

代码解析:

  1. 首先处理边界情况(空矩阵)
  2. 预处理阶段构建高度矩阵
  3. 对每一行的高度进行降序排序
  4. 计算以每个高度为矩形高度时的最大可能面积
  5. 遇到0时提前终止(因为已排序,后面都是0)

4. 复杂度分析与优化空间

4.1 时间复杂度

  • 预处理阶段:O(m×n)
  • 排序阶段:每行排序O(n log n),共m行 → O(m×n log n)
  • 总时间复杂度:O(m×n log n)

4.2 空间复杂度

  • 原地修改矩阵:O(1)
  • 若不能修改原矩阵:O(m×n)

4.3 可能的优化

  1. 使用计数排序:由于高度不超过m,可以用O(n)的计数排序替代通用排序,将时间复杂度降至O(m×n)
  2. 并行处理:不同行的处理相互独立,可以并行化

5. 实际应用场景与变种问题

5.1 实际应用

这种矩阵重排列技术可以应用于:

  • 图像处理中的最大全白区域查找
  • 数据压缩中的矩形块优化
  • 数据库中的密集区域分析

5.2 变种问题

  1. 限制重排次数:比如最多只能重排k列
  2. 三维版本:立方体中的最大全1子立方体
  3. 加权版本:不同位置的1有不同的权重

6. 常见错误与调试技巧

6.1 典型错误

  1. 忘记预处理阶段直接排序原矩阵
  2. 在计算面积时没有考虑排序后的索引关系
  3. 没有处理全0行的特殊情况

6.2 调试建议

  1. 先在小矩阵上手动计算验证
  2. 打印预处理后的高度矩阵检查是否正确
  3. 对每行的排序结果进行可视化

提示:在竞赛中遇到此类问题时,建议先在纸上画出几个小例子,手动模拟算法过程,这往往能快速发现思路中的漏洞。

7. 算法比较与替代方案

7.1 与最大矩形问题的关系

这道题是经典"最大矩形"问题的变种。原始问题(LeetCode 85)不允许重排列列,需要使用单调栈解法,时间复杂度O(m×n)。而本题通过允许列重排,使得我们可以使用更简单的贪心策略。

7.2 单调栈解法对比

虽然本题不需要,但了解单调栈解法有助于深入理解:

  1. 对每行构建高度数组
  2. 使用单调栈计算每个高度能扩展的最大宽度
  3. 时间复杂度也是O(m×n)

8. 进阶思考与扩展

8.1 如果允许行和列都重排?

这将变成一个完全不同的问题,最优解可能与图论中的团(clique)查找有关,难度会大幅增加。

8.2 动态版本

考虑矩阵中的值会动态更新,如何高效维护最大全1子矩阵?这需要更复杂的数据结构支持。

我在实际解决这个问题时发现,预处理阶段的高度计算是最容易出错的部分。特别是在处理第一行时,需要特别注意边界条件。另一个容易忽略的点是,当矩阵中所有元素都是0时,应该返回0而不是报错。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询