接雨水
看起来是一个实际的应用题,其实思路还是转化为求一个元素左右离它最近且比它大的元素的位置
此外,本题要求雨水,则要找到其左右两侧最矮的那一个,类似木桶效应,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
遇到相同高度的柱子,把第一个弹出,把第二个加入进去
class Solution {
public:
int trap(vector<int>& height) {
if(height.size()<=2) return 0;
stack<int> st;
st.push(0);
int sum=0;
for(int i=1;i<height.size();i++){
while(!st.empty()&&height[i]>height[st.top()]){
int mid=st.top();
st.pop();
if(!st.empty()){
int h=min(height[st.top()],height[i])-height[mid];
int w=i-st.top()-1;
sum+=h*w;
}
}
st.push(i);
}
return sum;
}
};
柱状图中最大的矩形
求能勾勒出来的最大的矩形面积
此题的关键就是要找到最高的柱子,所以要使栈头到栈底从大到小递减,进入的若比top大,则计算看是否能使矩阵面积更大
因为要找到左右界限,所以需要在height数组前后各加一个元素0
情况分析:注意这里,比如40,60,50,算出来的result先是601,再是502
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int result=0;
stack<int>st;
heights.insert(heights.begin(),0);
heights.push_back(0);// 数组尾部加入元素0
st.push(0);
for(int i=1;i<heights.size();i++){
if(heights[i]>=heights[st.top()]){
st.push(i);
}
else{
while(!st.empty()&&heights[i]<heights[st.top()]){
int mid=st.top();
st.pop();
if(!st.empty()){
int left=st.top();
int right=i;
int w=right-left-1;
int h=heights[mid];
result=max(result,w*h);
}
}
st.push(i);
}
}
return result;
}
};