矩阵的最大面积(单调栈)

通过图像解析,解决求矩形最大面积问题,联系到二维矩阵中寻找全为1的最大子矩阵。利用矩阵b,其中b[i][j]表示a中位置(i, j)向下连续1的数量。构建过程后,用单调栈处理b的每一行,找到最大矩形面积。" 110726211,10296860,优雅离职:java程序员的离职交接与准备指南,"['职场经验', 'Java开发', '离职管理', '职业素养', '沟通技巧']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

求图片中矩形最大的面积,类似于桶的容量由最短的木板决定的,见图片。

   

矩形的高度可以用数组表示,同时这个场景可以和另外一个场景联系起来:给定一个二维矩阵,矩阵中的元素只有0和1,求一个最大的子矩阵(要求子矩阵中的元素全是1) ,最大指的是矩阵中的1的数量最多。

下图中的矩阵 a 只包含1和0:

[1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 0, 0, 0]

[0, 1, 1, 1, 1, 0, 0, 0]

我们需要按照a矩阵来构造一个同样大小的矩阵 b:

[4, 5, 5, 5, 5, 3, 3, 1]
[3, 4, 4, 4, 4, 2, 2, 0]
[2, 3, 3, 3, 3, 1, 1, 0]
[1, 2, 2, 2, 2, 0, 0, 0]

[0, 1, 1, 1, 1, 0, 0, 0]

怎么构造的呢? 对于b中的任意一个元素b[i][j] 就是a中同样位置元素a[i][j] 的j列往“下”有多少连续个1,

完成b矩阵构造之后,就回到上面这个图了,我们以b中每一行为边去构造矩形,记录这个过程中产生的最大值,就是我们要求的答案了。

例如 [4, 5, 5, 5, 5, 3, 3, 1] 依次表示了矩形的高度,同时每个矩形的宽度都是1。使用单调栈来完成。

代码如下:

 public int getResult(char[][] matrix) {       //用什么方式来表示矩阵无所谓
         if(matrix.length==0){
             return 0;
         }
         
         int rows=matrix.length;
         int cols=matrix[0].length;
         int max=0;
         int tempMax=0;
         int[] dp=new int[cols+1];
         for(int i=0;i<rows;i++){
             Stack<Integer> stack=new Stack<>();      //单调栈,只记录元素的索引下标,这样就可以求出矩形的宽度了
             for(int j=0;j<cols+1;j++){
                 if(j<cols){             
                     if(matrix[i][j]=='1'){
                         dp[j]+=1;    //一直累加
                     }else{
                         dp[j]=0;
                     }
                 }
                 
                 if(stack.isEmpty() || dp[stack.peek()]<=dp[j]){
                     stack.push(j);
                 }else{
                     while(!stack.isEmpty() && dp[stack.peek()]>dp[j]){       //弹出比入栈元素大的栈顶元素
                         int temp=stack.pop();
                         tempMax=dp[temp]*(stack.isEmpty()?j:j-stack.peek()-1);    //dp[temp]表示的矩阵的高度,后面的乘数是矩形的宽度
                         max=Math.max(max,tempMax);
                     }
                     stack.push(j);
                 }
             }
         }
         return max;
     }

单调栈,就是栈中的要保持有序,这里是:栈低的元素最小,栈顶的元素最大。从栈低到栈顶是升序的。


    



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值