【Python刷题】LeetCode 1727 重新排列后的最大子矩阵

题目链接:https://leetcode.cn/problems/largest-submatrix-with-rearrangements/

题目描述

给定一个二进制矩阵 matrix,我们可以任意重排列矩阵的列。要求找到矩阵中全为 1 的最大子矩阵,并返回其面积。
示例 1:

输入 :matrix = \[0,0,1,1,1,1,1,0,1]
输出 :4
解释 :你可以按照上图方式重新排列矩阵的每一列。

最大的全 1 子矩阵是上图中加粗的部分,面积为 4 。

解题思路

这题让我们通过改变每一列 的顺序,来构建一个尽可能大的全 1 矩形 ,而这个矩形到底在整个矩阵的哪个位置是无法确定的,但是我们只要把矩形的底边所在的行给固定,那么问题就变简单了。只需要遍历所有行然后把以该行作为底边时能够得到的所有矩形找到,总是选取最大的矩阵就行了。

因此可以用一个非常形象的方式来理解:把矩阵看成一排楼房 ,我们通过改变地基来要找出能构成的最大矩形连续房间面积。

我们可以把矩阵的每一行当作当前的地基 ,每一列看作一栋楼 。数字 1 代表这一层有楼,数字 0 代表这一层是空的。因为题目允许我们任意重排列 ,就相当于我们可以自由调换这些楼的左右顺序 ,把它们从左到右、从高到低排列,遍历每一个楼,左边所有楼都比当前楼更高或一样高,所以从最左到当前位置,一定能画出一个完整矩形

整体思路非常直观:

  1. 遍历每一行,把它当作新的底边。
  2. 维护一个高度数组,记录每栋楼当前的总层数。
  3. 遇到 1 就把楼层加高一层,遇到 0 就直接把这栋楼坍塌为 0 层。
  4. 把所有楼按高度从高到低排序,从左往右依次计算能围成的最大矩形。
  5. 遍历过程中不断更新最大值,最后就是答案。

算法动图

代码实现

python 复制代码
class Solution:
    def largestSubmatrix(self, matrix: List[List[int]]) -> int:
        m,n=len(matrix),len(matrix[0])
        h=[0]*n#记录当前底边上的楼层的全部高度
        res=0
        for row in matrix:#遍历不同的底边
            for j in range(n):#遍历每栋楼楼
                h[j] = h[j]+1 if row[j] == 1 else 0#遇到1就扩建,遇到0就拆除
            sorted_h = sorted(h,reverse=True)#把楼层高度从高到低排列
            for i in range(0,n):#i从左到右遍历每栋楼,不停增加连续楼层的总宽度(i+1)
                res = max(res,sorted_h[i]*(i+1))#宽度乘当前楼高就是当前宽度能得到的最大面积,取最值
        return res

代码解释

  • m,n=len(matrix),len(matrix[0]):获取矩阵的行数和列数。
  • h=[0]*n:记录当前底边上,每一栋楼的楼层高度。
  • res=0:用来保存最终的最大面积。
  • for row in matrix:遍历每一行,把每一行当作一条新的底边。
  • for j in range(n):遍历每一栋楼。
  • h[j] = h[j]+1 if row[j] == 1 else 0:遇到 1 就扩建楼层,遇到 0 就直接拆除归零。
  • sorted_h = sorted(h,reverse=True):把所有楼按高度从高到低排列,因为列可以随便换顺序。
  • for i in range(0,n):从左到右一栋一栋看,连续的楼越来越多,宽度越来越大。
  • res = max(res,sorted_h[i]*(i+1)):当前宽度是 i+1,当前最矮的楼决定高度,相乘就是矩形面积,不断更新最大值。
  • 最后返回 res 就是全 1 最大子矩阵的面积。

复杂度分析

  • 时间复杂度:O(m * n log n)
    遍历每一行是 O(m),更新楼层高度 O(n),每次排序 O(n log n),整体为 O(m * n log n)。
  • 空间复杂度:O(n)
    只使用了一个一维数组记录楼层高度,额外空间很小。

总结

这道题最巧妙的地方,就是把二维矩阵的全 1 子矩形问题,转化成了楼层柱状图 问题。

再利用题目可以重排列的条件,直接排序贪心求解,思路清晰、代码简洁,是一道非常经典的贪心与矩阵结合的好题。

相关推荐
在所不辞兄6 小时前
刚性问题误差容限设置技巧
深度学习·神经网络·算法·机器学习
数智工坊6 小时前
视觉SLAM第10讲|后端优化(下):位姿图优化、滑动窗口与图优化工程实践
人工智能·深度学习·线性代数·矩阵
啊啊啊啊啊!!!!6 小时前
unordered_map和unordered_set的使用
算法
数智工坊7 小时前
视觉SLAM第13讲|工程落地:双目视觉里程计系统架构设计与性能优化
人工智能·深度学习·线性代数·性能优化·矩阵·系统架构·机器人
java_nnnn7 小时前
LeetCode刷题双指针(快乐数+盛最多水的容器)Java
算法·leetcode·职场和发展
yi01115 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦18 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下18 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J18 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛18 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法