普通单调栈模型
首先介绍单调栈模版
这个图里有5个数字,我们从右往左看,第一个数字是4,第二个数字是7,数字4小于数字7,所以7这个数之前的下一个更大值永远不会是4,那么此时4在数组里就相当于没有用了,所以我们需要一个数据结构来维护数据,保证我们可能需要的最大数字,那么我们想到了栈这种数据结构可以维护数据的出入并且保证是大数替换小数。
接着我们来模拟一遍单调栈的解题思路,首先我们将4压入栈中,接着把7压入栈中,发现7比4大,所以我们将栈中的4弹出,接着将数字7压入单调栈,然后将数字2压入栈中,发现2小于栈中的队首元素,所以2的下一个更大的数字为7,接着将5压入栈中,发现5要大于栈顶元素2,所以将栈顶元素弹出,接着将继续将5和栈顶比较,发现5小于7,所以5的下一个更大元素是7,随后将1与栈顶元素比较,发现1小于5,所以1的下一个更大元素是5
接下来给出模版:
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> arr(n);
stack<int> st;
vector<int> ans(n, -1); // 初始化为-1,表示没有更大的元素
// 读取输入
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
// 从右向左遍历
for (int i = n - 1; i >= 0; --i) {
// 弹出栈中所有小于当前元素的元素
while (!st.empty() && arr[i] >= arr[st.top()]) {
st.pop();
}
// 如果栈不为空,栈顶就是下一个更大元素的位置
if (!st.empty()) {
ans[i] = st.top();
}
// 将当前索引入栈
st.push(i);
}
// 输出结果(这里输出的是索引,也可以改成输出值)
for (int i = 0; i < n; i++) {
cout << ans[i] << " ";
}
return 0;
}
典型例题是力扣的739. 每日温度 - 力扣(LeetCode)
按照上述模版给出答案
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n=temperatures.size();
vector<int> ans(n);
stack<int> st;
for(int i=n-1;i>=0;i--)
{
int t =temperatures[i];
while(!st.empty()&&t>=temperatures[st.top()])
{
st.pop();
}
if(!st.empty())
{
ans[i]=st.top()-i;
}
st.push(i);
}
return ans;
}
};
本文参考了力扣的灵山爱抚茶的题单分享|【算法题单】单调栈(矩形面积/贡献法/最小字典序)- 讨论 - 力扣(LeetCode)