牛客网刷题之直方图最大面积

题目描述:
给出n个数字,代表直方图的条高,直方图每一条的宽度为1,请计算直方图中最大矩形的面积
在这里插入图片描述
上图是每条宽度为1, 高度 =[2,1,5,6,2,3].的直方图
在这里插入图片描述
图中的阴影部分是该直方图中面积最大的矩形,面积为10个单位
例如:
给出的高度 =[2,1,5,6,2,3],
返回10.
题目分析:
该题目在左神的算法课程中提到过使用单调栈的结构或思想,也就是使用栈或者一种类似于栈的先入后出的存储方式来解题目。构造一个从小到大的栈,只要遇到比当前栈顶元素大的值将其放入栈中(本题采用将元素的下标放入栈中,但概念是单调栈),如果遇到比栈顶小的元素,将其进行结算。结算的规则如下:

如果当前的栈顶元素对前面的元素没有归结则直接结算;
如果当前栈顶元素归结过前面的元素,则归结时将其归结记录加入

当前数组全部进入栈,剩余栈中的元素需要null对其进行归结,归结归入如上。

为什么要让小的元素归结大的元素以及记录前面元素的归结记录?

个人理解是:当前元素向右移动遇到比自己小的元素就不能进行移动了,因此需要小的元素将该元素归结;记录前面归结的记录是当前元素向左移动,当前元素归结的元素一定比当前元素大,可以左移,被其所归结的元素更大 ,因此也许进行记录。
代码如下:

import java.util.Stack;
public class Solution {
    public int largestRectangleArea(int[] height) {
    //边界判断,空数组直接返回0
       if(height.length==0) return 0;
       //定义栈,用来存放数组下标
		Stack<Integer> stack=new Stack<>();
		//定义额外的数组,记录当前的元素对于前面的元素是否归结,初始全0
		int[] arr=new int[height.length];
		stack.push(0);
		//记录最大面积的值,初始值最小
		int res=Integer.MIN_VALUE;
		int count=0;//记录当前元素归结元素的个数
         for(int i=1;i<height.length;i++) {
        	int sum=0;//记录归结的元素归结的元素个数
        	//遇到后面元素不能归结或者0元素,将归结记录置为0
        	if(!stack.isEmpty() &&height[stack.peek()]<=height[i]||height[i]==0) count=0;
        	//开始归结比当前元素大的栈中元素
        	while(!stack.isEmpty() && height[stack.peek()]>height[i]){
        		int tmp=stack.pop();
        		res=height[tmp]*(i+arr[tmp]-tmp)>res?height[tmp]*(i+arr[tmp]-tmp):res;
        		count++;
        		sum+=arr[tmp];
        	}
        	//记录当前元素的归结个数=归结的元素个数+归结元素所归结的个数
        	arr[i]=count+sum;
        	count=0;
        	stack.push(i);
        }
        //归结栈中剩余的元素
        while(!stack.isEmpty()) {
        /*	if(stack.size()==1) {
				int tmp=stack.pop();
				res= height.length*height[tmp]>res?height.length*height[tmp]:res;
				break;
			}*/
			int tmp=stack.pop();
			res=height[tmp]*(height.length+arr[tmp]-tmp)>res?height[tmp]*(height.length+arr[tmp]-tmp):res;
        }
		return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用单调栈求解直方图中最大矩形面积的C++完整代码: ```c++ #include <iostream> #include <stack> using namespace std; int getMaxArea(int hist[], int n) { stack<int> stk; int maxArea = 0, area = 0, i = 0; while (i < n) { if (stk.empty() || hist[stk.top()] <= hist[i]) { stk.push(i++); } else { int top = stk.top(); stk.pop(); area = hist[top] * (stk.empty() ? i : i - stk.top() - 1); if (area > maxArea) { maxArea = area; } } } while (!stk.empty()) { int top = stk.top(); stk.pop(); area = hist[top] * (stk.empty() ? i : i - stk.top() - 1); if (area > maxArea) { maxArea = area; } } return maxArea; } int main() { int hist[] = {6, 2, 5, 4, 5, 1, 6}; int n = sizeof(hist) / sizeof(hist[0]); cout << "The maximum area of the histogram is " << getMaxArea(hist, n) << endl; return 0; } ``` 在上述代码中,我们使用一个单调栈来维护直方图中的柱子。具体来说,我们从左到右遍历直方图中的柱子,如果当前柱子的高度不小于栈顶柱子的高度,则将当前柱子入栈;否则,我们弹出栈顶柱子,计算以该柱子高度为最小高度的矩形面积,更新最大面积值。在弹出栈顶柱子之后,当前柱子继续与栈顶柱子比较,直到当前柱子的高度不小于栈顶柱子的高度或者栈为空为止。 当所有的柱子都遍历完成后,我们需要将栈中剩余的柱子依次弹出,并根据弹出柱子的高度计算以该高度为最小高度的矩形面积,再次更新最大面积值。 最后,我们返回最大面积值即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值