LeetCode单调栈合集
Posted 头号理想
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode单调栈合集相关的知识,希望对你有一定的参考价值。
单调栈也是很常见的一种数据结构 在刷一些特定的题的时候 可以起到很好的效果
962 最大宽度坡
给定一个整数数组 A,坡是元组 (i, j),其中 i < j 且 A[i] <= A[j]。这样的坡的宽度为 j - i。
找出 A 中的坡的最大宽度,如果不存在,返回 0 。
暴力我试过了 超时 卡了四个用例(O(n^2)) 留下了不争气的口水
所以暴力的代码我也不贴了 丢人 直接用单调栈
从上边图可以看出 首先我们先正向遍历一遍数组 创建一个单调递减栈
如果当前栈为空或者是 当前元素小于栈顶元素 入栈
之后反向遍历一次数组 一旦元素符合条件(大于等于栈顶元素) 栈顶元素出栈 如果不出站 往前遍历没有意义
白白浪费时间复杂度
之后取最大值即可
注意:栈中保存的是最大值的下标 并不是最大值的元素值
代码
int maxWidthRamp(vector<int>& A)
stack<int> s;
for (int i = 0; i < A.size(); i++)
if (s.empty() || A[i] < A[s.top()])
s.push(i);
int ans = 0;
for (int j = A.size() - 1; j >= 0; j--)
while (!s.empty() && A[j] >= A[s.top()])
ans = max(ans, j - s.top());
s.pop();
return ans;
1019 链表中的下一个更大节点
给出一个以头节点 head 作为第一个节点的链表。链表中的节点分别编号为:node_1, node_2, node_3, … 。
每个节点都可能有下一个更大值(next larger value):对于 node_i,如果其 next_larger(node_i) 是 node_j.val,那么就有 j > i 且 node_j.val > node_i.val,而 j 是可能的选项中最小的那个。如果不存在这样的 j,那么下一个更大值为 0 。
返回整数答案数组 answer,其中 answer[i] = next_larger(node_i+1) 。
注意:在下面的示例中,诸如 [2,1,5] 这样的输入(不是输出)是链表的序列化表示,其头节点的值为 2,第二个节点值为 1,第三个节点值为 5 。
首先将链表中的元素放入一个数组中 比较方便操作
然后从后一次遍历数组 并且维护一个最大栈
(如果遇到比自己小的元素 加入栈中,如果比自己大 当前栈顶元素出栈 继续比较 然后元素入栈)
在维护最大栈的同时,如果现在的栈为空 那么当前所对应的位序的结果为0
如果不为空 当前位序结果为栈顶元素
vector<int> nextLargerNodes(ListNode* head)
stack<int> s;
vector<int> nums;
ListNode* p = head;
while (p != NULL)
nums.push_back(p->val);
p = p->next;
vector<int> ans(nums.size(), 0);//结果数组
for (int i = nums.size() - 1; i >= 0; --i)
while (!s.empty() && nums[i] >= s.top()) //最大栈的维护
s.pop();
ans[i] = s.empty() ? 0 : s.top();
s.push(nums[i]);
return ans;
每日温度
请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
这个题可以很容易的知道我们的结果 我们可以使用两层循环 但是不出意外结果会超时 这是我们就想到了单调栈
如果当前遍历到的元素大于栈顶元素 弹出栈中当前所有元素 然后将该元素小标添加到栈中
如果当前比例到的元素小于等于栈顶元素 直接将下标添加到栈中
这样如果在遍历过程中 遇到大的 自动计算下标之差 然后赋值即可
vector<int> dailyTemperatures(vector<int>& T)
stack<int>s;
vector<int> ans(T.size(), 0);//初始化都为0 为了只修改一部分元素(不用全部修改)
for (int i = 0; i < T.size(); i++)
while (!s.empty() && T[i] > T[s.top()])
int t = s.top(); s.pop();
ans[t] = i - t;//计算差值
s.push(i);
return ans;
下一个更大元素2
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
可能我们会发现这个题和上边的每日温度很相似 只不过每日温度不要求循环,这个题要求循环
仅此而已
所以我们完全可以把当前的数组 变成当前数组的二倍 然后取余即可
具体思路和上个题相同
vector<int> nextGreaterElements(vector<int>& nums)
if(nums.size()==0)
return ;
stack<int > s;
vector<int> ans(nums.size(), -1);
for (int i = 0; i < nums.size() * 2 - 1; i++)
while (!s.empty() && nums[i % nums.size()] > nums[s.top()])
ans[s.top()] = nums[i % nums.size()];
s.pop();
s.push(i % nums.size());
return ans;
希望以上所写对大家有帮助
以上是关于LeetCode单调栈合集的主要内容,如果未能解决你的问题,请参考以下文章