今天开启单调栈的篇章,一般什么时候采用单调栈?通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。
一、每日温度
题目描述:
思路和想法:
这里单调栈里只放数组下标,再了解栈的特点后,我们要考虑当前遍历元素和栈顶元素之间的大小关系,主要是有三种情况,temperatures[i] > temperatures[st.top()] ,temperatures[i] = temperatures[st.top()] 以及temperatures[i] < temperatures[st.top()]。
这里当 temperatures[i] > temperatures[st.top()]时,弹出元素,并用result记录一下。之后继续判断栈顶元素和当前遍历元素,直到temperatures[i] <= temperatures[st.top()],遍历下一个元素temperatures[i + 1]。
#include<vector>
#include<stack>
using namespace std;
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;
vector<int> result(temperatures.size(),0);
st.push(0);
for (int i = 1; i < temperatures.size(); i++)
{
if (temperatures[i] <= temperatures[st.top()])
{
st.push(i);
}
while (!st.empty() && temperatures[i] > temperatures[st.top()] )
{
result[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
return result;
}
};
二、下一个更大的元素I
题目描述:
思路和想法:
nums1是nums2的子集,并且还不重复,所以nums1的元素是一定能在nums2找到(唯一)。
(1)第一步:没有重复元素,我们可以用map来做映射。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。找到相应所在的位置
unordered_map<int, int> umap;
for (int i = 0; i < nums1.size(); i++) {
umap[nums1[i]] = i;
}
(2) 第二步就采用单调栈的方式,跟上个思路一致,可以获得右边第一个更大元素的数值。
#include<vector>
#include<stack>
#include<unordered_map>
using namespace std;
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> st;
vector<int> result(nums1.size(),-1);
if(nums1.size() == 0) return result;
unordered_map<int, int> umap;
for (int i = 0; i < nums1.size(); i++) {
umap[nums1[i]] = i;
}
st.push(0);
for (int j = 1; j < nums2.size(); j++)
{
if(nums2[j] <= nums2[st.top()]){
st.push(j);
}else{
while (!st.empty() && nums2[j] > nums2[st.top()]) {
if (umap.count(nums2[st.top()]) > 0) {
int index = umap[nums2[st.top()]];
result[index] = nums2[j];
}
st.pop();
}
st.push(j);
}
}
return result;
}
};