leetcode 1727. 重新排列后的最大子矩阵 中等

给你一个二进制矩阵 matrix ,它的大小为 m x n ,你可以将 matrix 中的 按任意顺序重新排列。

请你返回最优方案下将 matrix 重新排列后,全是 1 的最大子矩阵面积。

示例 1:

复制代码
输入:matrix = [[0,0,1],[1,1,1],[1,0,1]]
输出:4
解释:你可以按照上图方式重新排列矩阵的每一列。
最大的全 1 子矩阵是上图中加粗的部分,面积为 4 。

示例 2:

复制代码
输入:matrix = [[1,0,1,0,1]]
输出:3
解释:你可以按照上图方式重新排列矩阵的每一列。
最大的全 1 子矩阵是上图中加粗的部分,面积为 3 。

示例 3:

复制代码
输入:matrix = [[1,1,0],[1,0,1]]
输出:2
解释:由于你只能整列整列重新排布,所以没有比面积为 2 更大的全 1 子矩形。

示例 4:

复制代码
输入:matrix = [[0,0],[0,0]]
输出:0
解释:由于矩阵中没有 1 ,没有任何全 1 的子矩阵,所以面积为 0 。

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m * n <= 10^5
  • matrix[i][j] 要么是 0 ,要么是 1

分析:枚举子矩形的底边(最后一行),定义 heights[j] 表示从 matrix[i][j] 往上有多少个连续的 1(柱子的高度),问题变成:可以重排 heights。重排后,对于 heights 的连续子数组,子数组长度(矩形底边长)× 子数组最小值(矩形的高),即为全 1 子矩形的面积。枚举找到面积最大的子矩形。枚举子数组的长度 k=1,2,...,n,贪心地把 heights 最大的 k 个数排在一起,就可以让子数组的最小值(矩形的高)尽量大,从而得到最大的矩形面积。

对于 heights 的计算,如果 matrix[i][j]=0,那么 heights[j]=0。否则,把高度增加 1。形象地说,就是在柱子下面垫一块石头,把柱子抬高。

cpp 复制代码
class Solution {
public:
    int largestSubmatrix(vector<vector<int>>& matrix) {
        int m=matrix.size(),n=matrix[0].size(),ans=0;
        // printf("m=%d n=%d\n",m,n);
        vector<int>height;
        for(int i=0;i<m;++i)
        {
            // printf("i=%d\n",i);
            for(int j=0;j<n;++j)
            {
                if(!i)height.push_back(matrix[i][j]);
                else if(matrix[i][j])height[j]+=matrix[i][j];
                else height[j]=0;
            }
            vector<int>temp=height;
            sort(temp.begin(),temp.end());
            int len=0x3fffffff;
            for(int j=temp.size()-1,t=1;j>=0&&temp[j]>0;--j,++t)
            {
                len=min(len,temp[j]);
                ans=max(ans,len*t);
                // printf("i=%d j=%d t=%d len=%d temp=%d ans=%d\n",i,j,t,len,temp[j],ans);
            }
        }
        return ans;
    }
};
相关推荐
superior tigre2 小时前
347 前k个高频元素
数据结构·算法·leetcode
不想看见4042 小时前
Find All Numbers Disappeared in an Array数组--力扣101算法题解笔记
笔记·算法·leetcode
月明长歌2 小时前
【码道初阶-Hot100】LeetCode 438 + 567 对照详解:一套滑动窗口模板,彻底讲透“固定长度窗口 + 计数数组 + count维护”
算法·leetcode·滑动窗口
Elias不吃糖2 小时前
LeetCode-44 回溯解法
算法·leetcode·职场和发展
仟濹2 小时前
【算法打卡day25(2026-03-17 周二)今日算法:「回溯算法」】1-力扣17-电话号码的字母组合 2-力扣39-组合总和 3-力扣40-组合总和II
算法·leetcode·职场和发展
Storynone2 小时前
【Day26】LeetCode:452. 用最少数量的箭引爆气球,435. 无重叠区间,763. 划分字母区间
python·算法·leetcode
月明长歌2 小时前
【码道初阶-Hot100】LeetCode 3. 无重复字符的最长子串:从错误直觉到滑动窗口,彻底讲透为什么必须判断 `map.get(c) >= left`
java·算法·leetcode·哈希算法
junnhwan2 小时前
LeetCode Hot 100——贪心算法
java·算法·leetcode
Frostnova丶2 小时前
LeetCode 1727.重新排列后的最大子矩阵
算法·leetcode