《剑指offer》面试题59 - II. 队列的最大值

面试题59 - II.队列的最大值,中等题

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

输入:  
["MaxQueue","push_back","push_back",
"max_value","pop_front","max_value"] 
[[],[1],[2],[],[],[]] 
输出:  
[null,null,null,2,1,2]

输入: 
["MaxQueue","pop_front","max_value"] 
[[],[],[]]  
输出: 
[null,-1,-1]

题目讲解

解法1:常规解法

【核心思想】

  • 用两个队列来完成任务

【数据结构】

  • 队列与双向队列

【思路】

  • 用一个队列保存正常元素,另一个双向队列保存单调递减的元素
  • 入栈时,第一个队列正常入栈;第二个队列是递减队列,所以需要与之前的比较,从尾部把小于当前value的全部删除(因为用不到了)
  • 出栈时,第一个队列正常出栈;第二个队列的头部与出栈的值作比较,如果相同,那么一起出栈

【代码】

public class MaxQueue {
    Queue<Integer> queue;
    Deque<Integer> maxQueue;
    public MaxQueue() {
        queue=new ArrayDeque();
        maxQueue=new ArrayDeque();
    }
    public int max_value() {
        if(maxQueue.isEmpty())
            return -1;
        return maxQueue.peek();
    }
    public void push_back(int value) {
        queue.add(value);
        while(!maxQueue.isEmpty() && value>maxQueue.getLast())
            maxQueue.pollLast();
        maxQueue.add(value);
    }
    public int pop_front() {
        if(queue.isEmpty())
            return -1;
        int ans=queue.poll();
        if(ans==maxQueue.peek())
            maxQueue.poll();
        return ans;
    }
}

【备注】

  • 存储单调递减的元素的队列需要是双向队列
  • 如果面试官不允许用STL怎么办呢?自己手撸两个队列,解法如下。
解法2:提升解法

【数据结构】

  • 数组

【思路】

  • 使用head和tail标志,用两个数组模拟队列
  • 由题目的限制条件选择数组长度

【代码】

public class MaxQueue {
    int[] queue;
    int queueHead;
    int queueTail;
    int[] maxQueue;
    int maxQueueHead;
    int maxQueueTail;
    public MaxQueue() {
        queue=new int[20005];
        queueHead=0;
        queueTail=0;
        maxQueue=new int[20005];
        maxQueueHead=0;
        maxQueueTail=0;
    }
    public int max_value() {
        if(maxQueueTail==maxQueueHead)
            return -1;
        return maxQueue[maxQueueHead];
    }
    public void push_back(int value) {
        if(queueTail>=20000)
            throw new OutOfMemoryError();
        queue[queueTail++]=value;
        while(maxQueueHead!=maxQueueTail && value>maxQueue[maxQueueTail-1])//注意这边是从尾部开始比较的
            maxQueueTail--;
        maxQueue[maxQueueTail++]=value;
    }
    public int pop_front() {
        if(queueHead==queueTail)
            return -1;
        int ans=queue[queueHead];
        if(ans==maxQueue[maxQueueHead])
            maxQueueHead++;
        queueHead++;
        return ans;
    }
}

关注微信公众号“算法岗从零到无穷”,更多算法知识点告诉你。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值