📜  门| GATE CS 2011 |问题21(1)

📅  最后修改于: 2023-12-03 15:12:36.023000             🧑  作者: Mango

门 | GATE CS 2011 | 问题21

这是2011年计算机科学门考试中的第21个问题。本题目涉及到了数据结构和编程语言。

题目描述

构造一个队列数据结构,要求能够在 $O(1)$ 时间复杂度内执行以下操作:

  1. Enqueue(x):将元素 $x$ 插入到队列的尾部。
  2. Dequeue():将队列首部的元素弹出,并返回该元素。
  3. Max():返回队列中最大的元素。
解题思路

考虑使用一个双向队列 data 来存储元素,并维护一个双向队列 maximums,用于存储当前 data 中的最大值。

  1. Enqueue 操作:

    • 将元素 $x$ 插入到 queue 的尾部,并更新双向队列 maximums 中的元素。
  2. Dequeue 操作:

    • 如果 data 中队首元素是最大元素,那么将 maximums 中队首元素也弹出;
    • 弹出 data 队首元素。
  3. Max 操作:

    • 最大值即为 maximums 队首元素。
代码实现

Java 代码实现如下:

import java.util.Deque;
import java.util.LinkedList;

public class QueueWithMax {

    private Deque<Integer> data;
    private Deque<Integer> maximums;

    public QueueWithMax() {
        data = new LinkedList<>();
        maximums = new LinkedList<>();
    }

    public void Enqueue(int x) {
        data.addLast(x);
        while (!maximums.isEmpty() && maximums.getLast() < x) {
            maximums.removeLast();
        }
        maximums.addLast(x);
    }

    public int Dequeue() {
        if (data.isEmpty()) {
            throw new RuntimeException("no element in queue");
        }

        int x = data.removeFirst();
        if (x == maximums.getFirst()) {
            maximums.removeFirst();
        }

        return x;
    }

    public int Max() {
        if (maximums.isEmpty()) {
            throw new RuntimeException("no element in queue");
        }

        return maximums.getFirst();
    }
}

其中,Deque 是 Java 中提供的双向队列,由 LinkedList 实现。注意比较时要使用 removeFirst()getLast() 方法,而不是 pop()remove() 方法。

基本测试
QueueWithMax q = new QueueWithMax();
q.Enqueue(1);
q.Enqueue(3);
q.Enqueue(2);
System.out.println(q.Max()); // should return 3
q.Dequeue();
System.out.println(q.Max()); // should return 3
q.Dequeue();
System.out.println(q.Max()); // should return 2