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

26 Nov, 2021
Problem: Design a Data Structure a SpecialQueue which supports following operations enque, deque, getMin() or getMax() where getMin() operation takes O(1) time.Example:  
Let the data to be inserted in queue be -
4, 2, 1, 6

Operation     Queue       Output
push(4)         4           -
push(2)        4, 2         -
push(1)       4, 2, 1       -
getMin()      4, 2, 1       1
push(6)      4, 2, 1, 6     -
pop()         2, 1, 6       4
pop()          1, 6         2
pop()            6          1
getMin()         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: 
Enque
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: 
Java
C++
Python3
import java.util.*;import java.io.*; class SpecialQueue {       Queue<Integer> q;    Deque<Integer> 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());    }}
// C++ implementation to design// a queue data structure to get// minimum element in O(1) time #include <bits/stdc++.h> using namespace std; template <typename T> // Structure of the queueclass MinMaxQueue {public:         // Queue to store the    // element to maintain the    // order of insertion    queue<T> Q;         // Doubly ended queue to    // get the minimum element    // in the O(1) time    deque<T> 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 Codeint 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";}
# Python 3 implementation to design# a queue data structure to get# minimum element in O(1) timefrom 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 Codeif __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())
1
2
 
rajeev0719singh
vaibhavpatel1904
amartyaghoshgfg
Advanced Data Structure
Articles
Data Structures
Queue
Searching
Data Structures
Searching
Queue
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Proof that Dominant Set of a Graph is NP-Complete
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Cartesian Tree
Advantages of Trie Data Structure
Tree Traversals (Inorder, Preorder and Postorder)
SQL | Join (Inner, Left, Right and Full Joins)
find command in Linux with examples
Analysis of Algorithms | Set 1 (Asymptotic Analysis)
Understanding "extern" keyword in C