84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4
提示:
1 <= heights.length <=10^5
0 <= heights[i] <= 10^4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class Solution {
public int largestRectangleArea(int[] heights) {
int n=heights.length;
int []ph=new int [n+2];
int ans=0;
for(int i=1;i<n+1;i++) ph[i]=heights[i-1];
Deque<Integer> stack=new ArrayDeque<>();
for(int i=0;i<n+2;i++){
// System.out.println(i+" "+stack);
while(!stack.isEmpty()&&ph[stack.getLast()]>ph[i]){
int cur=stack.removeLast();
ans=Math.max(ans,(i-stack.getLast()-1)*ph[cur]);
}
stack.offer(i);
}
return ans;
}
}
|
这一题是干嘛呢?找到i左边和右边小于它的第一个数,中间就是最大面积了。
方法是单调栈。
注意栈里面记录的是下标。
在Java中使用的是ArrayDeque数据结构。
所以我建议看到有类似最右最左边找最小的数,优先来看看84是如何实现单调栈的。
我们每次弹出的时候做计算!!
为了加深印象,遂添加cpp题解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
vector<int> v(n+2);
for(int i=0;i<n;i++){
v[i+1]=heights[i];
}
stack<int> s;
int ans=0;
for(int i=0;i<n+2;i++){
while(!s.empty()&&v[s.top()]>v[i]){
int cur=s.top();
s.pop();
ans=max(ans,v[cur]*(i-s.top()-1));
}
s.push(i);
}
return ans;
}
};
|
难度中等402
给定一个整数数组 arr
,找到 min(b)
的总和,其中 b
的范围为 arr
的每个(连续)子数组。
由于答案可能很大,因此 返回答案模 10^9 + 7
。
示例 1:
1
2
3
4
5
|
输入:arr = [3,1,2,4]
输出:17
解释:
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。
最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。
|
示例 2:
1
2
|
输入:arr = [11,81,94,43,3]
输出:444
|
提示:
1 <= arr.length <= 3 * 104
1 <= arr[i] <= 3 * 104
通过次数20,094
提交次数58,149
注意也是在弹出栈的时候做计算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Solution {
public:
int sumSubarrayMins(vector<int>& arr) {
int n=arr.size();
vector<int> v(n+2);
for(int i=0;i<n;i++){
v[i+1]=arr[i];
}
stack<int> s;
int MOD=1000000007;
long ans=0;
for(int i=0;i<n+2;i++){
while(!s.empty()&&v[s.top()]>v[i]){
int cur=s.top();
s.pop();
// printf("left:%d,mid=%d right%d,\n",s.top(),(cur),(i));
ans+=1l*(i-cur)%MOD*(cur-s.top())%MOD*v[cur];
ans%=MOD;
}
s.push(i);
}
return (int)ans%MOD;
}
};
|