一、單調棧問題
單調棧問題通常是在一維數組中尋找任一個元素的右邊或者左邊第一個比自己大或者小的元素的位置。
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;}
};