直方图内矩形面积

输入一组直方图数据,其中每列的宽度为1,求所给直方图包含的最各个高度的矩形面积。比如,对于直方图[2,7,9,4,1],它所包含的各个高度矩形的面积为8,14,9,12,5
给定一个直方图及它的总宽度返回相应面积。

  • 方法一:
    方法一的思路是,从前完后遍历直方图,在相应的位置往前后搜索,遇到直方图高度更低的则停止,通过左右的界限来求其宽度。(方法一代码值考虑了值为0到9的情况)
#include <iostream>
using namespace std;
int main()
{
    cout<<"cin a histogram and the length n:";
    cout<<"such as [2,7,9,4,1],5"<<endl;
    string strin;
    getline(cin,strin);
    int last=strin.length()-1;
    int n=int(strin[last]-'0');
    int his[n+1];
    his[n]=0; 
    n=0;
    int sqr[n];
    for(int i=0;i<strin.length()-1;i++)
    {
        if(strin[i]<='9'&&strin[i]>='0')
        {
            his[n]=strin[i]-'0';
            n++;
        }
    }
    for(int i=0;i<n;i++)
    {
        int l=i,r=i;
        //往左搜索
        while(his[i]<=his[l] && l>=0)
        {
            l--;
        }
        //往右搜索
        while(his[i]<=his[r] && r<=n)
        {
            r++;
        }
        sqr[i]=(r-l-1)*his[i];
        cout<<his[i]<<' '<<sqr[i]<<endl;
    }
    return 1;
}
  • 方法二:
    方法二思路是:从左到右遍历直方图,定义一个栈,首先将直方图中第一个高度的序号入栈,往后搜索直方图,每次把栈顶元素对应的高度与当前搜索到的高度进行比较,如果当前高度高于栈顶元素,说明可以往下扩展,那么将当前高度的序号入栈。而如果当前高度低于栈顶元素对应直方图中高度,那么先求栈顶元素对应高度的矩形面积,由于当前高度低于栈顶元素高度,而栈顶元素的下一个元素对应的高度也是低于栈顶元素的(该元素是栈顶元素往左搜索的第一个高度更小的元素),因而,可以通过相应序号得到宽度。计算完该高度的矩形面积后,将栈顶元素出栈,继续比较新的栈顶元素对应高度与当前元素对应高度,仍然是栈顶元素对应高度更高,那么继续求其对应高度的矩形面积,依次循环。直到栈顶元素高度低于当前元素高度时入栈,继续往下。
    此处的小技巧是,把直方图第一个元素前一位和最后一个元素后一位高度都设置为0,这样方便求第一个和最后一个序号对应的直方图。且压入栈的的方柱的索引而不是高度,因为这样方便计算横向距离。
#include <iostream>
#include <stack>
using namespace std;
int main()
{
    string str;
    stack<int> hisstack;
    getline(cin,str);
    int* his=new int;
    int* sqr=new int;
    int n=1;
    for(int i=0;i<str.length();i++)
    {
        if(str[i]>='0'&& str[i]<='9')
        {
            his[n]=str[i]-'0';
            while(str[i+1]>='0'&& str[i+1]<='9')
            {
                his[n]=his[n]*10+int(str[i+1]-'0');
                i++;
            }
            n++;
        }
    }
    int num=his[n-1];
    his[n-1]=0; //把直方图之后一个高度设置为0 
    his[0]=0;  //把直方图之前一个高度设置为0 
    hisstack.push(0);          
    int hei=0;
    int wid=0;
    int curindex;
    for(int i=1;i<=num+1;i++)      
    {
        if(his[i]>=his[hisstack.top()])
        {
            hisstack.push(i);//将相应的编号入栈,方便求其横向差值
        }
        else
        { 
          while(his[i]<his[hisstack.top()])
          {
            hei=his[hisstack.top()];
            curindex=hisstack.top();
            hisstack.pop();
            wid=i-1-hisstack.top();
            sqr[curindex]=hei*wid;
          }
          hisstack.push(i);
        }   
    }
    for(int i=1;i<=num;i++)
    {
        cout<<his[i]<<' '<<sqr[i]<<endl;
    }
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弹指间LLL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值