请设计一个自助结账系统,该系统需要通过一个队列来模拟顾客通过购物车的结算过程,需要实现的功能有:
get_max()
:获取结算商品中的最高价格,如果队列为空,则返回 -1add(value)
:将价格为value
的商品加入待结算商品队列的尾部remove()
:移除第一个待结算的商品价格,如果队列为空,则返回 -1
注意,为保证该系统运转高效性,以上函数的均摊时间复杂度均为 O(1)
示例 1:
输入:
["Checkout","add","add","get_max","remove","get_max"]
[[],[4],[7],[],[],[]]
输出: [null,null,null,7,4,7]
示例 2:
输入:
["Checkout","remove","get_max"]
[[],[],[]]
输出: [null,-1,-1]
提示:
1 <= get_max, add, remove 的总操作数 <= 10000
1 <= value <= 10^5
思路:
1、队列实现入队出队操作。
2、双端队列实现获取当前队列最大值的作用,具体来说,队列入队时,双端队列也入队,但
在每次入队时,如果队尾元素小于即将入队的元素,则将小于的元素全部出队后,再入队;否则直接入队。
3、双端队列保存的时当前队列的最大值,当队列出队时,判断出对元素是否与双端队列队首元素相等,相等则同样出队,否则不变。
代码实现:
class Checkout {
public:
Checkout() {
}
int get_max() {
return max_q.empty() ? -1 : max_q.front();
}
void add(int value) {
q.push(value);
while(!max_q.empty() && max_q.back() < value)
max_q.pop_back();
max_q.push_back(value);
}
int remove() {
if(q.size() == 0)
return -1;
int tmp = q.front();
if(max_q.front() == tmp)
max_q.pop_front();
q.pop();
return tmp;
}
private:
queue<int>q;
deque<int>max_q;
};
/**
* Your Checkout object will be instantiated and called as such:
* Checkout* obj = new Checkout();
* int param_1 = obj->get_max();
* obj->add(value);
* int param_3 = obj->remove();
*/