单调栈运用

来源:互联网 发布:eve数据地点出什么 编辑:程序博客网 时间:2024/06/08 12:06

题目:

给定一个整形矩阵 ,其中数值只有0和1两种,求其中全是1的所有矩形中,最大矩形区域1的数量。

如:1 1 1 0其中最大矩形区域有3个1,所以返回3

1 0 1 1

1 1 1 1

1 1 1 0

其中最大矩形区域有6个1,所以返回6


解题思路:

建立一个数组,里面存储矩阵的行,将其中的数据表示直方图的高度,运用单调栈找每个数离他最近且小于他的数。时间复杂度O(n*m)

JAVA程序:

package chapter_1_stackandqueue;


import java.util.Stack;


public class Problem_09_MaximalRectangle {


public static int maxRecSize(int[][] map) {
if (map == null || map.length == 0 || map[0].length == 0) {
return 0;
}
int maxArea = 0;
int[] height = new int[map[0].length];
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
height[j] = map[i][j] == 0 ? 0 : height[j] + 1;
}
maxArea = Math.max(maxRecFromBottom(height), maxArea);
}
return maxArea;
}


public static int maxRecFromBottom(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int maxArea = 0;
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (i - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
stack.push(i);
}
while (!stack.isEmpty()) {
int j = stack.pop();
int k = stack.isEmpty() ? -1 : stack.peek();
int curArea = (height.length - k - 1) * height[j];
maxArea = Math.max(maxArea, curArea);
}
return maxArea;
}


public static void main(String[] args) {
int[][] map = { { 1, 0, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 0 }, };
System.out.println(maxRecSize(map));
}


}


C++程序:

#include<iostream>
#include<stdlib.h>
#include<stack>
using namespace std;


int findmax(int* len,int col);


int fun(int (*a)[4],int raw,int col)
{
int max=0;



if(a==NULL||col==0||raw==0)
return 0;


int* len=new int[col]();
for(int i=0;i<raw;i++)
{
       for(int j=0;j<col;j++)
{
len[j]=a[i][j]==0?0:len[j]+1;


}
  max=max>findmax(len,col)?max:findmax(len,col);
}
delete []len;
return max;
}


int findmax(int* len,int col)
{
stack<int> sta;
int max=0;
for(int i=0;i<col;i++)
{
 while(!sta.empty()&&len[i]<=len[sta.top()])
 {
 int j=sta.top();
 sta.pop();
 int k=sta.empty()?-1:sta.top();
 int curr=len[j]*(i-k-1);
 max=max>curr?max:curr;
 }


 sta.push(i);
}


while(!sta.empty())
{
int j=sta.top();
 sta.pop();
 int k=sta.empty()?-1:sta.top();
 int curr=len[j]*(col-k-1);
 max=max>curr?max:curr;
}


return max;
}




int main()
{
int a[3][4]={{1,0,1,1},{1,1,1,1},{1,1,1,0}};
int max=fun(a,3,4);
cout<<max<<endl;


system("pause");
return 0;
}