代码编织梦想

单调栈解题模板

单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)

本文就通过几道算法题来看看单调栈模板的使用。

一.单调栈模板

给一个数组,返回一个等长的数组,对应索引存储着下一个更大元素,如果没有更大的元素,就存 -1。

函数签名如下:

vector<int> nextGreaterElement(vector<int>& nums);

比如说,输入一个数组nums = [2,1,2,4,3],你返回数组[4,2,4,-1,-1]。

解释:第一个 2 后面比 2 大的数是 4; 1 后面比 1 大的数是 2;第二个 2 后面比 2 大的数是 4; 4 后面没有比 4 大的数,填 -1;3 后面没有比 3 大的数,填 -1。

暴力解很容易想到:

public int[] nextGreaterElement(int[]nums){
	int n = nums.length;
	int[] nums1 = new int[n];
	int index=0;
	for(int i=0;i<n;i++){
		for(int j=i+1;j<n;j++){
			if(nums[j]>nums[i])
				nums1[index++] =nums[j];
				break;
			nums1[index++]=-1; 
		}
	}
}

这个问题可以这样抽象思考:把数组的元素想象成并列站立的人,元素大小想象成人的身高。这些人面对你站成一列,如何求元素「2」的 Next Greater Number 呢?很简单,如果能够看到元素「2」,那么他后面可见的第一个人就是「2」的 Next Greater Number,因为比「2」小的元素身高不够,都被「2」挡住了,第一个露出来的就是答案。

在这里插入图片描述

public int[] nextGreaterElement(int[]nums){
	int nums3 = new int[nums.length];
	Stack<Integer>st =new Stack<Integer>();
	for(int i=nums.length-1;i>=0;i--){
		//判断个子高矮
		while(!st.isEmpty()&&st.peek()<=nums[i])
			//矮的就去掉
			st.pop();
		//这时候还能看见的第一个,说明就是最近的比本数大的。
		nums3[i] =st.isEmpty()?-1:st.peek();
		st.push(nums[i]);
	}
	return nums3;
}

二.问题变形

这次相当于是数组里存放的不是数本身,而是对应的索引间距。

在这里插入图片描述

public int[] dailyTemp(int []T){
	int n = T.length;
	int []nums = new int[n];
	//单调栈用来存放高的元素
	Stack<Integer> st = new Stack<>();
	//从后往前放入
	for(int i =n-1;i>=0;i--){
		while(!st.isEmpty()&&T[st.peek()]<=T[i])
			//温度低的都抛掉
			st.pop();
		nums[i] = st.isEmpty()?0:(st.peek()-i);
		st.push(i);
	}
	return nums;
}

三. 如何处理环形数组

这里主要得熟悉如何构造环形数组,一般通过取模操作:

int[] arr = {1,2,3,4,5};
int n = arr.length, index = 0;
while (true) {
    print(arr[index % n]);
    index++;
}

常用套路是将数组长度翻倍,但这里可以不用额外构造,使用循环数组实现:

 public int[] nextGreaterElements(int[] nums) {
        int n= nums.length;
        int [] nums1 = new int [n];
        Stack<Integer>st = new Stack<>();
        for(int i=2*n-1;i>=0;i--){
            while(!st.isEmpty()&& st.peek()<=nums[i%n])
                st.pop();
            nums1[i%n] = st.isEmpty()?-1:st.peek();
            st.push(nums[i%n]);
        }
        return nums1;
    }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xunbaobao123/article/details/115329291

单调栈原理及应用 详解 附各种类型的题目练习_棉花糖灬的博客-爱代码爱编程_单调递增栈

欢迎关注我的个人博客:www.zuzhiang.cn   定义: 单调栈,顾名思义,是栈内元素保持一定单调性(单调递增或单调递减)的栈。这里的单调递增或递减是指的从栈顶到栈底单调递增或递减。既然是栈,就满足后进先出的特点。与之相对应的是单调队列。     实现: 例如实现一个单调递增的栈,比如现在有一组数10,3,7,4,12。从左到右依次入

左 . 进阶算法---单调栈_duoduo18up的博客-爱代码爱编程

单调栈: 问题描述:给定一个数组 请确定每个元素左右距离最近的比它大的数字 常规想法:  到某一个元素时   通过两个for 分别获取其左边比它大的和右边比他大的数字  时间复杂度为O(n2) 最优解思路(单调栈): 1  一个按照从大到小顺序排序的栈结构    若在压栈过程中发现要压栈的元素和栈顶的元素相比要大  则弹出当前栈顶元素 并从开始弹出

找出数组中每个数右边第一个比它大的元素--时间复杂度o(n)单调栈解法-爱代码爱编程

题目:给定一个整型数组,数组元素随机无序的,要求打印出所有元素右边第一个大于该元素的值。 如数组A=[1,5,3,6,4,8,9,10] 输出[5, 6, 6, 8, 8, 9, 10, -1] 如数组A=[8, 2, 5, 4, 3, 9, 7, 2, 5] 输出[9, 5, 9, 9, 9, -1, -1, 5, -1] 1、暴力遍历 我们很容

[数据结构]——单调栈_lucky52529的博客-爱代码爱编程_什么是单调栈

单调栈 笔者在做leetcode的题(下一个出现的最大数字)时,接触到了单调栈这一种数据结构,经过研究之后,发现单调栈在解决某些问题时出奇的好用,下面是对单调栈的性质和一些典型题目。 什么是单调栈? 从名字上就听的出来

算法:单调栈_shelldawn的博客-爱代码爱编程

问题A: 不重复未排序数组,找到每个位置左边和右边比其小且最近的元素: 单调栈,O(N) 要找到右边最小,则维护一个递增的栈,直到碰到小值,弹出比其小的值,并更新弹出元素的最近小值。 注:栈里保存下标,通过下标访问数组值

单调栈_canaryw的博客-爱代码爱编程

根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高的天数。如果之后都不会升高,请输入 0 来代替。 例如,给定一个列表 temperatures = [73, 74, 75, 71, 6

算法-单调栈-爱代码爱编程

单调栈 题目 在力扣刷算法题时刷到这道题,觉得涉及到的算法很有意思。 根据每日气温列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [

算法-单调栈问题合集-爱代码爱编程

算法-单调栈问题合集 1、移掉K位数字,使剩下的数字保持最小2、移掉K位数字,使剩下的数字保持最大3、去除重复字母,使字典序最小 单调栈顾名思义是一种单调递增或者单调递减的栈,虽然很简单,但是的确是一种高级数据结构。 之前我写的文章 算法-摩天大楼问题 是采用单调栈进行优化的。 算法-滑动窗口最大值则是维护了一个单调队列来解决问题 借助

教你如何使用单调栈解题-爱代码爱编程

开篇 懒癌晚期最近疯狂发作,连着三四天没有更新博客,没有刷PAT,感觉到了最熟悉的期末搁置阶段(简称越到期末越放松)。今天终于提起精神来完成每日任务了,希望在离开家的前几天可以每天更新一篇面试类文章吧。 今天我们仍然说数据结构(算法部分暂时搁置,因为本人最近也在充实算法领域的其他新鲜知识,等把最近的那本书看完再来继续更新纯算法博客).今天是一种非常重要的

单调栈与单调队列算法详解及LeetCode经典题目(Python)-爱代码爱编程

单调栈 单调栈:栈内的元素按照某种方式排序下单调递增或单调递减,如果新入栈的元素破坏的单调性,就弹出栈内元素,直到满足单调性。 单调栈分为单调递增栈和单调递减栈: 单调递增栈:栈中数据出栈的序列为单调递减序列;单调递减栈:栈中数据出栈的序列为单调递增序列。维护单调栈 维护单调递增栈: 遍历数组中每一个元素,执行入栈:每次入栈前先检验栈顶元素和进栈

单调栈解题模板秒杀三道算法题-爱代码爱编程

学算法认准 labuladong 后台回复进群一起力扣???? 读完本文,可以去力扣解决如下题目: 496.下一个更大元素I(Easy) 503.下一个更大元素II(Medium) 1118.一月有多少天(Medium) 单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)

单调栈算法总结&专题训练-爱代码爱编程

单调栈算法总结&专题训练 1.概述2.模板3.例题T1:T2:T3:T4:T5:4.总结 1.概述 单调栈,是一种数据结构,与单调队列相似。 单调队列使用双端队列维护,队列内元素单调递增或单调递减。 单调栈则使用普通的栈维护,栈内元素单调递增或单调递减。 接下来,通过一道例题,来看一下单调栈的基本操作。 2.模板 link

有趣的算法题~单调栈-爱代码爱编程

在刷 LeetCode 的时候,每次遇到精彩的题解都会感叹数据结构的伟大,通过巧妙地设计,能够非常清晰明了的解决问题。   什么是单调栈 单调栈分为单调递增栈和单调递减栈,单调递增栈即栈内元素保持单调递增的栈,同理单调递减栈即栈内元素保持单调递减的栈,跟单调队列差不多,但是只用到它的一端,利用它可以用来解决一些 ACM/ICPC 和 OI 的题目,如