【Day41 LeetCode】单调栈问题
一、单调栈问题
单调栈问题通常是在一维数组中寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。
1、每日温度 739
这题的目的是对于当天,找到未来温度升高的那一天,也就是当前元素的右边第一个比自己大的元素。所以我们需要维护一个单调栈,栈内元素非严格单调递减。
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> q;
vector<int> ans(temperatures.size());
for(int i=0; i<temperatures.size(); ++i){
while(!q.empty() && temperatures[q.top()] < temperatures[i]){
ans[q.top()] = i - q.top();
q.pop();
}
q.push(i);
}
return ans;
}
};
2、下一个更大元素 I 496
一种思路是采用哈希表记录nums2(全集)元素的下一个更大的元素,寻找下一个更大的元素的过程就可以使用单调栈来进行辅助。代码如下:
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> mp;
stack<int> q;
for(int num : nums2){
while(!q.empty() && q.top() < num){
mp[q.top()] = num;
q.pop();
}
q.push(num);
}
while(!q.empty()){
mp[q.top()] = -1;
q.pop();
}
vector<int> ans(nums1.size());
for(int i=0; i<nums1.size(); ++i)
ans[i] = mp[nums1[i]];
return ans;
}
};
还有一种就是记录nums1(子集)的索引,在循环nums2中采用单调栈,找到元素的下一个更大的元素。
3、下一个更大元素II 503
这题数组可以循环,所以可以理解为有两个数组拼接在一起,求第一个数组的下一个更大元素。一个技巧是在一个数组里遍历两次,这样可以不用将代码扩容,更加简洁方便。
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n, -1);
stack<int> q;
for(int i=0; i<2*n; ++i){
while(!q.empty() && nums[q.top()] < nums[i%n]){
ans[q.top()] = nums[i%n];
q.pop();
}
q.push(i%n);
}
return ans;
}
};