求一个数,从这个数往左起第一个比他小的下标,O(1)复杂度

Largest Rectangle in a Histogram
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 21306 Accepted: 6865

Description

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles: 

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

Input

The input contains several test cases. Each test case describes a histogram and starts with an integer  n, denoting the number of rectangles it is composed of. You may assume that  1<=n<=100000. Then follow  n integers  h1,...,hn, where  0<=hi<=1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is  1. A zero follows the input for the last test case.

Output

For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.

Sample Input

7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

Sample Output

8

4000

这真的是一道非常非常好的题,网上很多人说这是一道DP题,但我看到的DP的代码和利用堆栈的代码差不多,也就是说,这道题利用

堆栈其实他的核心思想和DP的做法类似,那么这符合一道DP题的特征吗。DP题一般具有以下三个特征:1:最优化原理;2:无后效性

3:有重叠子问题。DP这个解决问题的思想之所以在解决这类问题时很有优势就在于有重叠子问题这一点。那么看完这三个特征,我们

来对这道题一一对号入座。1:最优化原理,额,这个恕我直言,很难对接起来,2:无后效性,这个可以。3:有重叠子问题,额,恕我直言

以我目前的水平看不出来。所以似乎只符合一条,所以以我目前的水平来看,这似乎不是一道DP题,而是一道巧妙地解题思维题。

这道题再次告诉我:你所认为的打死都不会是O(n)复杂度的东西,在巧妙的解题方法面前就是O(1)。

#include<iostream>
#include<stdio.h>
using namespace std;
int n;
int a[100001];
int L[100001];
int R[100001];

long long ans;

void solve()
{
	int i,j;
	int stack[100001];
	int t=0;
	for(i=0;i<n;i++)
	{
		while(t>0 && a[stack[t-1]]>=a[i]) t--;
		
		L[i]= (t==0)?0 : (stack[t-1]+1);
		stack[t++]=i;
	}
	
	t=0;
	for(i=n-1;i>=0;i--)
	{
		while(t>0 && a[stack[t-1]]>=a[i]) t--;
		
		R[i]= (t==0)?n : (stack[t-1]);
		stack[t++]=i;
	}
	
	for(i=0;i<n;i++)
	{
		ans=max(ans,(long long)a[i]*(R[i]-L[i]));
	}
	
	printf("%lld\n",ans);
}
int main()
{
	while(~scanf("%d",&n) && n)
	{
		int i,j;
		for(i=0;i<n;i++)
		scanf("%d",&a[i]);
		ans=0;
		solve();
	}
	return 0;
}


### 回答1: 将它插入到组中,并保持组仍然有序。 可以使用二分查找来找到要插入的位置,然后将该插入到组中。具体步骤如下: 1. 定义要插入的组。 2. 使用二分查找找到要插入的位置。 3. 将该插入到组中。 4. 输出插入后的组。 示例代码: ``` num = 5 arr = [1, 3, 4, 6, 8] # 二分查找 left = right = len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == num: pos = mid break elif arr[mid] < num: left = mid + 1 else: right = mid - 1 else: pos = left # 插入 arr.insert(pos, num) # 输出结果 print(arr) ``` 输出结果为:`[1, 3, 4, 5, 6, 8]`。 ### 回答2: 如果该组中存在,则输出其在组中的位置(下标从0开始计算);如果该组中不存在,则将该插入到组中相应的位置,并输出插入后的组。 首先,我们需要输入一个已排好序的组,既然组已排好序,那么我们可以选择二分查找算法来查找输入的是否存在于组中。如果输入的组中存在,那么我们就可以通过二分查找算法得到它在组中的位置。如果输入的组中不存在,我们需要找到它应该插入到组中的位置,然后将它插入到该位置。 二分查找算法的基本原理是将组分成两部分,每次比较中间位置的与输入的的大小,如果中间位置的比输入的大,则继续查找半部分,反之则查找右半部分,直到找到输入的或者确定输入的不存在于组中。 如果找到了输入的,我们就可以直接输出它在组中的位置,否则就可以找到它应该插入到组中的位置。我们可以通过二分查找算法得到这个位置,然后将组中该位置及其之后的向后移动一位,最后将输入的插入到这个位置上。 下面是一段示例代码: ```python def insert_num(num, arr): left = 0 right = len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == num: return mid elif arr[mid] < num: left = mid + 1 else: right = mid - 1 pos = left arr.insert(pos, num) return pos, arr ``` 我们可以将要查找的传入函`insert_num(num, arr)`中,函返回值分为两种情况: - 如果输入的组中已存在,函返回该组中的位置; - 如果输入的组中不存在,函返回它应该插入到组中的位置及插入后的组。 需要注意的是,该代码只对已排好序的组有效,如果组没有排好序,我们需要先对组进行排序。 ### 回答3: 题目要一个已排好序的组中输入一个,然后将这个插入到组中,还要保持组的有序性。这是一道很基础的算法题,可以采用插入排序的思路实现。 插入排序的核心思想是:将待插入的元素与已有序的序列从后往前依次比较,找到插入位置并插入。在插入元素后,需要移动其后面的元素,以保证组的有序性。 对于这道题,我们可以先遍历一遍组,找到待插入元素的位置(即第一个大于或等于待插入元素的位置),然后将其插入到该位置。插入元素后,后面的元素需要依次后移一位,直到插入元素所在的位置为止。 具体实现如下: 1. 定义一个变量来存储待插入的元素。 2. 遍历组,找到待插入元素的位置。 3. 将待插入元素插入到对应位置。 4. 插入元素后,将后面的元素依次后移一位,直到插入元素所在的位置。 5. 返回新组。 下面是一份完整的代码实现: ```python def insert_sorted_array(arr, num): # 定义一个变量来存储待插入的元素 insert_num = num # 遍历组,找到待插入元素的位置 for i in range(len(arr)): if arr[i] >= num: # 将待插入元素插入到对应位置 arr.insert(i, insert_num) break # 插入元素后,将后面的元素依次后移一位,直到插入元素所在的位置 for j in range(i+1, len(arr)): arr[j], insert_num = insert_num, arr[j] # 返回新组 return arr ``` 该算法时间复杂度为 O(n),空间复杂度为 O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值