单调栈
参考文章:单调栈题解秒杀三道算法题
顾名思义,单调栈本质是一个栈。只不过里面的元素是单调递增或者递减的。它的用途不是很广泛,只处理一种叫做Next Greater Element
的典型问题。
1. 下一个更大元素
- 题目描述
给定一个数组,返回一个等长的数组,对应索引存储着下一个更大的元素值。
如果没有更大的元素,返回-1。
这是一个典型的Next Greater Element
问题,因此使用单调栈模板来解决。
vector<int> nextGreaterElement(vector<int>& nums){
vector<int> ans(nums.size()); //存放答案的数组
stack<int> s;
//倒着入栈,其实是正着出栈
for (int i = nums.size()-1;i>=0;i--){
//将队列中比nums[i]的元素移除,因为被挡住了,没有什么用
while (!s.empty() && s.top()<=nums[i]){
s.pop();
}
//s.top() 是第一个比nums[i]大的元素,因为比它小的都被移除了
ans[i] = s.empty()?-1:s.top();
//入栈,进行下一轮比较
s.push(nums[i]);
}
return ans;
}
2. 处理循环数组
- 题目描述
假设给的数组是环形的。例如:给定一个数组[2,1,2,4,3],返回[4,2,4,-1,4]。3绕了一圈找到比它大的数字4。
这种题同样是有模板的,假设给定的数组翻倍,那么 3 是不是就能找到比自己大的数字了。
vector<int> nextGreaterElement(vector<int>& nums){
int n = nums.size();
vector<int> ans(n); //存放答案的数组
stack<int> s;
//假设数组翻倍
for (int i =2*n-1;i>=0;i--){
// nums[i%n],通过这种方法来模拟环形
while (!s.empty() && s.top()<=nums[i%n]){
s.pop();
}
//s.top() 是第一个比nums[i]大的元素,因为比它小的都被移除了
ans[i%n] = s.empty()?-1:s.top();
//入栈,进行下一轮比较
s.push(nums[i%n]);
}
return ans;
}