剑指 Offer 59 - II. 队列的最大值

这篇博客介绍了如何利用C++实现一个队列,同时支持常数时间复杂度的max_value、push_back和pop_front操作。核心思想是维护一个辅助双端队列s2,确保其始终存储当前队列s1的最大值。当新元素加入时,通过比较和调整保持s2的降序,从而能在常数时间内获取最大值。在弹出队首元素时,若弹出的元素与s2队首相同,则s2也弹出一个元素。

题目描述:

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/

思路:

首先想到了用两个栈实现队列那道题,但仔细一想这两个题有本质区别,这里的push和pop都可以直接用队列的函数实现,关键是如何找最大值。我一开始想用栈存储,即每次都比较栈顶和新元素的值,那个大就往栈里push哪个,问题出在当最大的元素被pop,栈里还是存储该最大值。
其实我们想要的不过是,保证另一个队列头是目前这个队列的最大值,这样就可以直接pop出来。所以当一个新元素被压入队列,它也应该被压入另一个队列,但要保证该队列是降序的,即如果该元素小于队尾元素,就直接push进,如果该元素大于队尾元素,就要把队尾的pop出来,再次比较新队尾和该元素的大小,直到该元素被push进去。当需要pop出队首元素,存储最大值的那个队列按理说也需要pop出来一个,但是只有在存储最大值队列的队首元素和原队列被pop出来的元素相同,存储最大值的队列才会pop。
这样我们看到,存储最大值的队列既需要pop队尾元素,又需要pop队首元素,所以需要一个双端队列deque。

c++代码:

class MaxQueue {
public:
queue<int> s1;
    deque<int> s2;
    MaxQueue() {

    }
    
    int max_value() {
        return s1.empty()?-1:s2.front();
    }
    
    void push_back(int value) {
        s1.push(value);
            while((!s2.empty())&&(s2.back())<value)
                s2.pop_back();
            
            s2.push_back(value);
        
    }
    
    int pop_front() {
        if(s1.empty())
            return -1;
        int t=s1.front();
        s1.pop();
        if(t==s2.front())
            s2.pop_front();
        return t;
        /*if(s1.empty()) return -1;
        int res=s1.front();
        s1.pop();
        if(res==s2.front())
            s2.pop_front();
        return res;*/
    }
    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值