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

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

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

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

分析:利用两个栈定义队列,再用一个栈存放最大值。(x)

进一步分析:队列的特点是先进先出,若要判断其max或min,不能直接采用栈的方式。假设队列元素为942353637。若采用栈的方式第一个元素9低于个进,同样也会第一个出去。由于后面数均小于9,辅助栈中也不存在其他元素,也就是说,9一出去,辅助栈为空,无法判断。。。。。。那么需要利用一个辅助队列,辅助队列不仅要留最大数,还得留小于最大数的数。

​ 按照下图进一步分析:

​ 队列2中第一个进入的元素是9,若只保留最大数,则9出去后,辅助队列不再存在其他元素,无法求最大值,故需将7也放入队列2中,即步骤2-1。

​ 之后再进8,由于8大于7,9出队列之后、8出队列之前,最大值均是8,7无作用,故可删除7,进8,(步骤2-2)

​ 同样,9仅队列后,8也不发挥作用,故删除8(步骤2-3)

​ 之后进入3,再进入4,4>3,故保留4即可。

​ 以此类推

​ 直到最后一个元素5进去,5大于3,故3删除,5大于4,4删除。辅助队列仅存995.

在这里插入图片描述

总结起来,辅助队列中存在元素的作用为:辅助队列元素能掌控的范围为队列中其位置之前的元素。第2个9的范围为1-3.5的范围为4-9.(可将辅助队列看做是将军,即队列1中的小兵一定得被辅助队列的将军所掌管)

在这里插入图片描述

class MaxQueue {

public:

  MaxQueue() {



  }

  

  int max_value() {

​    if (q2.empty()) return -1;

​    return q2.front();

  }

  

  void push_back(int value) {

​    // q1 push

​    q1.push_back(value);

​    // q2 push

​    while (!q2.empty() && q2.back() < value)

​    {

​      q2.pop_back();

​    }

​    q2.push_back(value);

  }

  

  int pop_front() {

​    if (q1.empty()) return -1;

​    else

​    {

​      if (q1.front() == q2.front()) q2.pop_front();

​      int popvalue = q1.front();

​      q1.pop_front();

​      return popvalue;

​    }

  }

private:

  deque<int> q1, q2;

};



/**

 \* Your MaxQueue object will be instantiated and called as such:

 \* MaxQueue* obj = new MaxQueue();

 \* int param_1 = obj->max_value();

 \* obj->push_back(value);

 \* int param_3 = obj->pop_front();

 */

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值