《剑指offer第二版》面试题59 题目二:队列的最大值(java)

题目描述

  • 请定义一个队列实现函数max得到队列里的最大值。要求函数max、push_back和pop_front的时间复杂度都为O(1)。

解题思路

  1. 用双端队列maximums保存最大值。用currentIndex记录push进队列数字的index。
  2. push_back的时候,如果push的值number大于maximums的队尾元素,则删除队尾元素,直到maximums中没有比number小的值。
  3. pop_front的时候,如果pop的数据对应的index和maximums队首元素对应的index值一样,则移除maximums的队首元素。
  4. maximums的队首元素即为当前队列的最大值。

代码

static class QueueWithMax {
    static class InternalData{
        int number;
        int index;
        InternalData(int n, int i) {
            this.number = n;
            this.index = i;
        }
    }
    Deque data = new LinkedList<>(); // 存储队列数据
    Deque maximums = new LinkedList<>(); // 存储最大值的队列
    int currentIndex = -1; //记录push进队列的index

    public void push_back(int number){
        currentIndex ++;
        while (!maximums.isEmpty() && number > maximums.peekLast().number) {
            // number大于maximums的队尾元素,则删除队尾元素,直到maximums中没有比number小的值。
            maximums.pollLast();
        }
        InternalData idata = new InternalData(number, currentIndex);
        maximums.offer(idata);
        data.offer(idata);
    }

    public int pop_front(){
        if (maximums.isEmpty()) {
            throw new RuntimeException("queue is empty!");
        }
        InternalData idata = data.poll();
        if (idata.index == maximums.peek().index) {
            // 如果pop的数据对应的index和maximums队首元素对应的index值一样,则移除maximums的队首元素。
            maximums.poll();
        }
        return idata.number;
    }

    public int max(){
        if (maximums.isEmpty()) {
            throw new RuntimeException("queue is empty!");
        }
        return maximums.peek().number;
    }

}

你可能感兴趣的:(《剑指offer第二版》面试题59 题目二:队列的最大值(java))