单调栈
设计单调栈的目的是为了解决一些需要快速找到某个区间最大/最小值的问题
设计单调栈的主要目的是解决特定类型的问题,使得问题可以更高效、更简单地被解决。
单调栈具有单调性质,即栈中元素的值保持单调递增或单调递减。这种单调性质在解决问题时非常有用。例如,当需要快速找到一个数列中每个元素的下一个更大元素时,可以使用单调递减栈来解决,其时间复杂度为O(n)。如果不使用单调栈,该问题的时间复杂度将是O(n²),显然效率更低。
因此,设计单调栈可以使得某些问题可以变得更加高效,而且解决问题的方法也更加简单。但是需要注意的是,并不是所有问题都可以使用单调栈来解决,因此需要对问题进行仔细分析,才能决定是否需要使用单调栈。
调栈是一种特殊的栈,它具有单调性质,即栈中元素的值保持单调递增或单调递减。通常使用单调递增栈和单调递减栈两种类型,分别用于解决不同类型的问题。
在单调递增栈中,栈顶元素为当前栈中最大的元素,新的元素进栈时,将栈中所有比它小的元素依次弹出,直到栈顶元素大于等于该元素,然后将该元素入栈。这样保证栈中元素的单调递增。
而在单调递减栈中,栈顶元素为当前栈中最小的元素,新的元素进栈时,将栈中所有比它大的元素依次弹出,直到栈顶元素小于等于该元素,然后将该元素入栈。这样保证栈中元素的单调递减。
单调栈的应用非常广泛,例如可以用单调递减栈来解决"下一个更大元素"类问题,用单调递增栈来解决"下一个更小元素"类问题,还可以用于图算法中的拓扑排序等问题。
class MyQueue {
Deque<Integer> deque = new LinkedList<>();
//弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
//同时判断队列当前是否为空
void poll(int val) {
if (!deque.isEmpty() && val == deque.peek()) {
deque.poll();
}
}
//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
//保证队列元素单调递减
//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
void add(int val) {
while (!deque.isEmpty() && val > deque.getLast()) {
deque.removeLast();
}
deque.add(val);
}
//队列队顶元素始终为最大值
int peek() {
return deque.peek();
}
}
作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)