Largest Rectangle In a histogram

题目描述

挑战程序设计的解题思路:

样例对应的答案
在这里插入图片描述
在这里插入图片描述

由于每个元素只压入和弹出一次,因此复杂度是O(2N),即O(N)的,同样对于R,也可以用同样的方式求出
自己的理解:以H[i]为一段区间的最小高度,如何求出该区间呢?{以该高度向左右两边依次扩展,以左边为例,左端点L[i]一定是满足H[j]<H[i] (j<i)最大的j,同理,右端点R[i]一定是满足H[j]<H[i] (j>i)最大的j 最后的答案便是max(H[i]*(R[i)-L[i]+1)(0<=i<N) ,这道题用栈来求解L[i]真是太精巧了,首先栈里面的元素一定是递增的,因为是按照序号来的嘛,我一开始有个疑问,为什么弹出的元素对后续比较没有影响呢?原因是:当比较到H[i]时,假设弹出的集合是S,S中的高度值都是大于等于H[i],直到栈顶H[st[t]]的高度是小于H[i]的,才记录结果L[i]=st[t]+1,再将H[i]压入栈中,之后比较H[i+1],如果H[i]>=H[i+1],那么集合S中的高度值显然也会是>=H[i+1],因为S>=H[i]
#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
ll N;
const ll maxn=1e5+7;
ll L[maxn],R[maxn],st[maxn],h[maxn];//区间的左端点,区间的右端点,栈,高度
ll solve()
{
	ll i,j,t=0;
	for(i=0;i<N;i++)//计算L[i]
	{
		while(t>0&&h[st[t-1]]>=h[i])
		t--;
		L[i]=t==0?0:st[t-1]+1;
		st[t++]=i;		
	}
	t=0;
	for(i=N-1;i>=0;i--)//计算R[i]
	{
		while(t>0&&h[st[t-1]]>=h[i])
		t--;
		R[i]=t==0?0:st[t-1]-1;
		st[t++]=i;
	}
	ll res=0;
	for(i=0;i<N;i++)
	res=max(res,h[i]*(R[i]-L[i]+1));
	return res;
}
int main()
{
//  freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	ll i,j;
	cin>>N;
	for(i=0;i<N;i++)
	cin>>h[i];
	ll res=solve();
//	for(i=0;i<N;i++)
//	cout<<L[i]<<" "<<R[i]<<endl;
	cout<<res<<endl;	
	return 0;
}
看了书上这个巧妙的解法,以后遇到区间问题也要多考虑考虑能不能用栈解决了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值