单调栈
下一个更大元素1
题目链接
维护一个单调递减栈,即当遍历元素大于栈顶元素时就要保存结果并弹出栈顶元素
为了以子集数组1的顺序得出结果,我们需要对数组2操作时利用哈希表等来建立映射关系
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> st;
unordered_map<int,int> hash;
for(int i=0;i<nums2.size();i++){
while(!st.empty()&&nums2[i]>st.top()){
hash[st.top()]=nums2[i];
st.pop();
}
st.push(nums2[i]);
}
while(!st.empty()){
hash[st.top()]=-1;
st.pop();
}
vector<int> res;
for(int i=0;i<nums1.size();i++){
res.push_back(hash[nums1[i]]);
}
return res;
}
};
下一个最大元素2
题目链接
循环数组,处理方法只需将数组长度变为2倍,即构造成一个逻辑上收尾相接的环
遍历时利用取余即可
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n=nums.size();
vector<int> res(n,-1);
stack<int> st;
for(int i=0;i<n*2-1;i++){
while(!st.empty()&&nums[i%n]>nums[st.top()]){
res[st.top()]=nums[i%n];
st.pop();
}
st.push(i%n);
}
return res;
}
};
每日温度
题目链接
这个题跟找下一个最大元素的题目一样
我们需要维护一个单调递减栈,即当前遍历元素大于栈顶元素时保存结果并弹出栈顶元素
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
vector<int> res(temperatures.size(),0);
for(int i=0;i<temperatures.size();i++){
while(!st.empty()&&temperatures[i]>temperatures[st.top()]){
int tempd=st.top();
st.pop();
res[tempd]=i-tempd;
}
st.push(i);
}
return res;
}
};
移掉K位数字
class Solution {
public:
string removeKdigits(string num, int k) {
stack<char> s;
for (int i = 0; i < num.size(); i++)
{
while (!s.empty() && s.top() > num[i] && k)
{
s.pop();
k--;
}
if (s.empty() && num[i] == '0')
continue;//跳过前置0
s.push(num[i]);
}
string result;
while (!s.empty())
{
if (k > 0)//当还要再移除数字的时候:从此时单调递增栈的top部删去数字
k--; //k>0时,那么此时说明string全部元素都以单调栈的形式进入栈中
//(string都用完了都单调递增了但是k还可以继续删除)
//k没有用完,栈里面肯定是全部单调递增
//因此将后面大的元素pop掉就行
else if (k == 0)//当不用再移除数字的时候:把字符串取出来到result
result += s.top();
s.pop();
}
reverse(result.begin(), result.end());//stl中的reverse函数
return result == "" ? "0" : result;
}
};
柱状图最大矩形
题目链接
找边界问题,矩形面积是由左右两边的最小高度决定的
因此,维护一个单调递增栈,即当遍历元素小于栈顶元素时,就要去计算以栈顶元素为代表的那一个矩形面积,左边界为栈顶元素位置,右边界为当前遍历位置,高度为栈顶值
- 此题代码出注意的地方在于,收尾个加入一个0元素,表示收尾元素的边界
这样可以使得代码简便,如果不加最后还需要一个循环来把栈中所剩的元素代表的矩形计算一遍
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
if(heights.size()==0) return 0;
//if(heights.size()==1) return heights[0];
heights.push_back(0);
heights.insert(heights.begin(),0);
stack<int> st;
int maxArea=0;
for(int i=0;i<heights.size();i++){
while(!st.empty()&&heights[i]<heights[st.top()]){
int h=heights[st.top()];
st.pop();
int width=i-st.top()-1;
maxArea=max(maxArea,h*width);
}
st.push(i);
}
return maxArea;
}
};
接雨水
题目链接
与前面那个矩形面积大致相同,此题主要找两个边界,遍历元素要大于栈顶元素,找波谷
class Solution {
public:
int trap(vector<int>& height) {
stack<int> st;
int sum=0;
for(int i=0;i<height.size();i++){
while(!st.empty()&&height[i]>height[st.top()]){
int right=height[i];
int mid=st.top();
st.pop();
if(!st.empty()){
int h=min(height[st.top()],right)-height[mid];
int w=i-st.top()-1;
sum+=h*w;
}
}
st.push(i);
}
return sum;
}
};