1.单调栈
1.什么是单调栈?
单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。
2.单调栈一般解决什么问题?
通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。
3.单调栈需要考虑什么?
- 单调栈里存放的元素是什么?单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
- 单调栈里元素是递增呢? 还是递减呢?
4.单调栈需要判断的条件
- 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
2.739每日温度
1.解题思路
由于题目中需要找到右边第一个比今天大的温度,与单调栈的思路相匹配,所以本题使用单调栈来解决问题。
2.具体实现
st存放的是顺序遍历时还未找到右边第一个比今天大的温度。
ret存放的是对应的右边第一个比今天大的温度数组,默认情况下全为-1。
- 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况,没有找到右边的大于的元素,直接入栈
- 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况,没有找到右边的大于的元素,直接入栈
- 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况,找到了右边的大于的元素,出栈放到对应下标位置的ret,继续判断,直到遇到不大于的元素之后结束出栈操作,然后将当前值入栈
- 由前面的可以看出,这个st存放的是一个单调递减的。
-
while(!st.empty()&&temperatures[st.top()] < temperatures[i]){ ret[st.top()] = i - st.top(); //cout<<st.top()<<i-st.top()<<endl; st.pop(); } st.push(i);
3.具体代码
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
stack<int> st;//存放的是下标
int n = temperatures.size();
vector<int> ret(n,0);
st.push(0);
for(int i = 1;i<n;i++){
//cout<<st.top()<<temperatures[st.top()]<<i-st.top()<<endl;
if(temperatures[st.top()]>temperatures[i]){
st.push(i);
}else if(temperatures[st.top()]== temperatures[i]){
st.push(i);
}else{
while(!st.empty()&&temperatures[st.top()] < temperatures[i]){
ret[st.top()] = i - st.top();
//cout<<st.top()<<i-st.top()<<endl;
st.pop();
}
st.push(i);
}
}
return ret;
}
};