# Design a Queue data structure to get minimum or maximum in O(1) time

Problem: Design a Data Structure a SpecialQueue which supports following operations enqueue, deque, getMin() or getMax() where getMin() operation takes O(1) time.
Example:

`Let the data to be inserted in queue be -4, 2, 1, 6Operation     Queue       Outputpush(4)         4           -push(2)        4, 2         -push(1)       4, 2, 1       -getMin()      4, 2, 1       1push(6)      4, 2, 1, 6     -pop()         2, 1, 6       4pop()          1, 6         2pop()            6          1getMin()         6          6// Notice the getMin() function call// It returns the minimum element // of all the values present in the queue`

Approach: The idea is to use Doubly ended Queue to store in increasing order if the structure is to return the minimum element and store in decreasing order if the structure is to return the maximum element. The operations of the Data Structure is defined as follows:

Enqueue

• Insert the element into the queue structure.
• If the size of the Deque structure is empty that is the size of the Deque is 0. Then, Insert the element from the back.
• Otherwise, If there are some elements in the Deque structure then pop the elements out from the Deque until the back of the Deque is greater than the current element and then finally insert the element from back.

Deque

• If the first element of the Deque is equal to the front element of the queue then pop the elements out from the Queue and the Deque at the same time.
• Otherwise, Pop the element from the front of the queue to maintain the order of the elements.

Get Minimum

Return the front element of the Deque to get the minimum element of the current element of the queue.
Below is the implementation of the above approach:

## C++

 `// C++ implementation to design``// a queue data structure to get``// minimum element in O(1) time` `#include ` `using` `namespace` `std;` `template` `<``typename` `T>` `// Structure of the queue``class` `MinMaxQueue {``public``:``    ``// Queue to store the``    ``// element to maintain the``    ``// order of insertion``    ``queue Q;` `    ``// Doubly ended queue to``    ``// get the minimum element``    ``// in the O(1) time``    ``deque D;` `    ``// Function to push a element``    ``// into the queue``    ``void` `enque_element(T element)``    ``{``        ``// If there is no element``        ``// in the queue``        ``if` `(Q.size() == 0) {``            ``Q.push(element);``            ``D.push_back(element);``        ``}``        ``else` `{``            ``Q.push(element);` `            ``// Pop the elements out``            ``// until the element at``            ``// back is greater than``            ``// current element``            ``while` `(!D.empty() && D.back() > element) {``                ``D.pop_back();``            ``}``            ``D.push_back(element);``        ``}``    ``}` `    ``// Function to pop the element``    ``// out from the queue``    ``void` `deque_element()``    ``{``        ``// Condition when the Minimum``        ``// element is the element at``        ``// the front of the Deque``        ``if` `(Q.front() == D.front()) {``            ``Q.pop();``            ``D.pop_front();``        ``}``        ``else` `{``            ``Q.pop();``        ``}``    ``}` `    ``// Function to get the``    ``// minimum element from``    ``// the queue``    ``T getMin() { ``return` `D.front(); }``};` `// Driver Code``int` `main()``{``    ``MinMaxQueue<``int``> k;``    ``int` `example[3] = { 1, 2, 4 };` `    ``// Loop to enque element``    ``for` `(``int` `i = 0; i < 3; i++) {``        ``k.enque_element(example[i]);``    ``}``    ``cout << k.getMin() << ``"\n"``;``    ``k.deque_element();``    ``cout << k.getMin() << ``"\n"``;``}`

## Java

 `import` `java.io.*;``import` `java.util.*;` `class` `SpecialQueue {` `    ``Queue q;``    ``Deque dq;` `    ``public` `SpecialQueue()``    ``{``        ``q = ``new` `LinkedList<>();``        ``dq = ``new` `ArrayDeque<>();``    ``}` `    ``void` `enque(``int` `data)``    ``{``        ``// remove all elements from``        ``// from deque which are greater``        ``// than the current element 'data'``        ``while` `(!dq.isEmpty() && dq.getLast() > data) {``            ``dq.removeLast();``        ``}``        ``// If queue is empty then``        ``// while loop is skipped.``        ``dq.addLast(data);``        ``q.add(data);``    ``}` `    ``void` `deque()``    ``{``        ``// If min element is present``        ``// at front of queue``        ``if` `(dq.getFirst() == q.peek()) {``            ``dq.removeFirst();``        ``}``        ``q.remove();``    ``}` `    ``// Method to get min element in Queue``    ``int` `getMin() ``throws` `Exception``    ``{``        ``// If queue is Empty, return Exception``        ``if` `(q.isEmpty())``            ``throw` `new` `Exception(``"Queue is Empty"``);``        ``else``            ``return` `dq.getFirst();``    ``}``    ``public` `static` `void` `main(String[] args) ``throws` `Exception``    ``{``        ``SpecialQueue arr = ``new` `SpecialQueue();``        ``arr.enque(``1``);``        ``arr.enque(``2``);``        ``arr.enque(``4``);``        ``System.out.println(arr.getMin());``        ``arr.deque();``        ``System.out.println(arr.getMin());``    ``}``}`

## Python3

 `# Python 3 implementation to design``# a queue data structure to get``# minimum element in O(1) time``from` `collections ``import` `deque as dq` `# class for the queue`  `class` `MinMaxQueue:` `    ``def` `__init__(``self``):``        ``# Queue to store the``        ``# element to maintain the``        ``# order of insertion``        ``self``.Q ``=` `dq([])` `        ``# Doubly ended queue to``        ``# get the minimum element``        ``# in the O(1) time``        ``self``.D ``=` `dq([])` `    ``# Function to push a element``    ``# into the queue``    ``def` `enque_element(``self``, element):``        ``# If there is no element``        ``# in the queue``        ``if` `(``len``(``self``.Q) ``=``=` `0``):``            ``self``.Q.append(element)``            ``self``.D.append(element)` `        ``else``:``            ``self``.Q.append(element)` `            ``# Pop the elements out``            ``# until the element at``            ``# back is greater than``            ``# current element``            ``while` `(``self``.D ``and``                   ``self``.D[``-``1``] > element):``                ``self``.D.pop()` `            ``self``.D.append(element)` `    ``# Function to pop the element``    ``# out from the queue` `    ``def` `deque_element(``self``,):``        ``# Condition when the Minimum``        ``# element is the element at``        ``# the front of the Deque``        ``if` `(``self``.Q[``0``] ``=``=` `self``.D[``0``]):``            ``self``.Q.popleft()``            ``self``.D.popleft()` `        ``else``:``            ``self``.Q.popleft()` `    ``# Function to get the``    ``# minimum element from``    ``# the queue` `    ``def` `getMin(``self``,):``        ``return` `self``.D[``0``]`  `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``k ``=` `MinMaxQueue()``    ``example ``=` `[``1``, ``2``, ``4``]` `    ``# Loop to enque element``    ``for` `i ``in` `range``(``3``):``        ``k.enque_element(example[i])` `    ``print``(k.getMin())``    ``k.deque_element()``    ``print``(k.getMin())`

## C#

 `using` `System;``using` `System.Collections.Generic;` `class` `SpecialQueue {``    ``Queue<``int``> q;``    ``List<``int``> dq;` `    ``public` `SpecialQueue()``    ``{``        ``q = ``new` `Queue<``int``>();``        ``dq = ``new` `List<``int``>();``    ``}` `    ``void` `Enque(``int` `data)``    ``{``        ``// remove all elements from``        ``// from deque which are greater``        ``// than the current element 'data'``        ``while` `(dq.Count > 0 && dq[dq.Count - 1] > data) {``            ``dq.RemoveAt(dq.Count - 1);``        ``}``        ``// If queue is empty then``        ``// while loop is skipped.``        ``dq.Add(data);``        ``q.Enqueue(data);``    ``}` `    ``void` `Deque()``    ``{``        ``// If min element is present``        ``// at front of queue``        ``if` `(dq[0] == q.Peek()) {``            ``dq.RemoveAt(0);``        ``}``        ``q.Dequeue();``    ``}` `    ``// Method to get min element in Queue``    ``int` `GetMin()``    ``{``        ``// If queue is Empty, return Exception``        ``if` `(q.Count == 0) {``            ``throw` `new` `Exception(``"Queue is Empty"``);``        ``}``        ``else` `{``            ``return` `dq[0];``        ``}``    ``}` `    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``SpecialQueue arr = ``new` `SpecialQueue();``        ``arr.Enque(1);``        ``arr.Enque(2);``        ``arr.Enque(4);``        ``Console.WriteLine(arr.GetMin());``        ``arr.Deque();``        ``Console.WriteLine(arr.GetMin());``    ``}``}` `// This code is contributed by phasing17`

## Javascript

 `class MinMaxQueue {``  ``constructor() {``    ``// Queue to store the element to maintain the order of insertion``    ``this``.Q = [];` `    ``// Doubly ended queue to get the minimum element in the O(1) time``    ``this``.D = [];``  ``}` `  ``// Function to push a element into the queue``  ``enqueElement(element) {``    ``// If there is no element in the queue``    ``if` `(``this``.Q.length === 0) {``      ``this``.Q.push(element);``      ``this``.D.push(element);``    ``} ``else` `{``      ``this``.Q.push(element);` `      ``// Pop the elements out until the element at back is greater than current element``      ``while` `(``this``.D.length > 0 && ``this``.D[``this``.D.length - 1] > element) {``        ``this``.D.pop();``      ``}` `      ``this``.D.push(element);``    ``}``  ``}` `  ``// Function to pop the element out from the queue``  ``dequeElement() {``    ``// Condition when the Minimum element is the element at the front of the Deque``    ``if` `(``this``.Q[0] === ``this``.D[0]) {``      ``this``.Q.shift();``      ``this``.D.shift();``    ``} ``else` `{``      ``this``.Q.shift();``    ``}``  ``}` `  ``// Function to get the minimum element from the queue``  ``getMin() {``    ``return` `this``.D[0];``  ``}``}` `// Driver Code``function` `main() {``  ``const k = ``new` `MinMaxQueue();``  ``const example = [1, 2, 4];` `  ``// Loop to enque element``  ``for` `(let i = 0; i < 3; i++) {``    ``k.enqueElement(example[i]);``  ``}` `  ``console.log(k.getMin());``  ``k.dequeElement();``  ``console.log(k.getMin());``}` `main();` `// This code is contributed by phasing17`

Output
```1
2
```

Time and Space of Complexity of Each Function:
enque function:

• Time complexity: O(N), where N is the number of elements in the deque
• Auxiliary Space: O(N)

deque() method:

• Time complexity: O(1)
• Auxiliary Space: O(1)

getMin() method:

• Time complexity: O(1)
• Auxiliary Space: O(1)

Previous
Next