HackerRank Largest Rectangle

题目链接

Problem Statement

There are N buildings in a certain two-dimensional landscape. Each building has a height given by hi,i[1,N] . If you join K adjacent buildings, they will form a solid rectangle of area K×min(hi,hi+1,,hi+k1) .

Given N buildings, find the greatest such solid area formed by consecutive buildings.

Input Format
The first line contains N , the number of buildings altogether.
The second line contains N space-separated integers, each representing the height of a building.

Constraints
1N105
1hi106

Output Format
One integer representing the maximum area of rectangle formed.

Sample Input

5
1 2 3 4 5

Sample Output

9

Explanation

An illustration of the test case follows.

.


#include<stdio.h>			//Largest Rectangle
#include<string.h>
#include<stdlib.h>
#define MAXN 100001
#define MAXH 1000001
/*
算法思想:
对于数组中的每一个元素a[i],计算以a[i]作为最小值的矩形的面积area,求出最大的面积即可。

为了计算以a[i]作为最小值的矩形的面积,我们需要知道a[i]之前第一个比a[i]小的元素索引(leftindex)以及a[i]之后第一个比a[i]小
的元素索引(rightindex),这样以[i]作为最小值的矩形的面积即为a[i]*(前后索引之间的距离)

利用数据结构栈(栈内元素递增),将数组元素依次与栈顶元素比较,当栈空时,直接入栈,当栈顶元素小于等于数组元素时,数组元素
直接入栈,否则,栈顶元素出栈直至栈顶元素小于等于数组元素,再将数组元素入栈。当所有元素都遍历过之后,若栈非空,则一次弹栈,
并计算相应的面积,直至栈空即可

为了能够知道a[i]的leftindex和rightindex,在数组元素入栈时需要记录元素的索引
*/

int a[MAXN], stack[MAXN];
int top = -1;
int area[MAXN];			//记录以元素a[i]为最小值的矩形的面积
int index[MAXN];		//记录栈中元素的原来序号(即A[i]的i)

int FindMax(int n)
{
	int i, leftindex, rightindex, max=0;
	for (i = 0; i < n; i++)
	{
		if (top < 0 || (top >= 0 && stack[top]<=a[i]))		//直接入栈
		{
			stack[++top] = a[i];
			index[top] = i;
		}
		else
		{
			while (top >= 0 && stack[top] > a[i])
			{
				//计算以栈顶元素作为最小值的矩形的面积
				//top>0时,right即为i,leftindex为栈顶元素之前元素的索引,即index[top-1]
				//top==0时,rightindex和rightindex之间的距离即为i
				area[index[top]] = stack[top] * (top > 0 ? (i - index[top - 1] - 1) : i);
				if (max < area[index[top]]) max = area[index[top]];		//找最大
				top--;
			}
			stack[++top] = a[i];
			index[top] = i;
		}
	}
	while (top >= 0)		//数组元素遍历完毕,若栈非空,则将栈中元素依次出栈,并计算相应的面积
	{
		area[index[top]] = stack[top] * (top > 0 ? (i - index[top - 1] - 1) : i);
		if (max < area[index[top]]) max = area[index[top]];
		top--;
	}
	return max;
}

int main()
{
	int n, i;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", a + i);
	printf("%d\n", FindMax(n));
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值