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单调栈合集的主要内容,如果未能解决你的问题,请参考以下文章

739. 每日温度 (单调栈)

739. 每日温度 : 单调栈模板题

单调栈——每日温度

单调栈——每日温度

单调队列&单调栈归纳

LeetCode- 柱状图中最大的矩形(单调栈)