单调栈
设计单调栈的目的是为了解决一些需要快速找到某个区间最大/最小值的问题
设计单调栈的主要目的是解决特定类型的问题,使得问题可以更高效、更简单地被解决。
单调栈具有单调性质,即栈中元素的值保持单调递增或单调递减。这种单调性质在解决问题时非常有用。例如,当需要快速找到一个数列中每个元素的下一个更大元素时,可以使用单调递减栈来解决,其时间复杂度为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();
}
}