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

被折叠的 条评论
为什么被折叠?



