单调栈

参考:https://www.bilibili.com/video/BV1Y441117gR/?from=search&seid=9796499757209042214&spm_id_from=333.337.0.0&vd_source=46d50b5d646b50dcb2a208d3946b1598

设计单调栈的目的是为了解决一些需要快速找到某个区间最大/最小值的问题

设计单调栈的主要目的是解决特定类型的问题,使得问题可以更高效、更简单地被解决。

单调栈具有单调性质,即栈中元素的值保持单调递增或单调递减。这种单调性质在解决问题时非常有用。例如,当需要快速找到一个数列中每个元素的下一个更大元素时,可以使用单调递减栈来解决,其时间复杂度为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();
    }
}
posted @ 2023-03-26 11:03  Chenyi_li  阅读(44)  评论(0编辑  收藏  举报