Design a stack to retrieve original elements and return the minimum element in O(1) time and O(1) space

Our task is to design a Data Structure SpecialStack that supports all the stack operations like push(), pop(), isEmpty(), isFull() and an additional operation getMin() which should return minimum element from the SpecialStack. All these operations of SpecialStack must be performed with time complexity O(1). To implement SpecialStack, you should only use standard Stack data structure and no other data structure like arrays, list etc.

Example:

Consider the following Special-Stack
16  --> TOP
15
29
19
18

When getMin() is called it should return 15, which is the minimum 
element in the current stack. 

If we do pop two times on stack, the stack becomes
29  --> TOP
19
18

When getMin() is called, it should return 18 which is the minimum 
in the current stack.


An approach that uses O(1) time and O(1) extra space is discussed here. However, in the previous article the original elements are not recovered. Only the minimum element is returned at any given point of time.

In this article, the previous approach is modified so that original elements can also be retrieved during a pop() operation.

Approach:
Consider a variable minimum in which we store the minimum element in the stack. Now, what if we pop the minimum element from the stack? How do we update the minimum variable to the next minimum value? One solution is to maintain another stack in sorted order so that the smallest element is always on the top. However, this is an O(n) space approach.
To achieve this in O(1) space, we need a way to store the current value of an element and the next minimum value in the same node. This can be done by applying simple mathematics:

new_value = 2*current_value - minimum

We push this new_value into the stack instead of current_value. To retrieve current_value and next minimum from new_value:

current_value = (new_value + minimum)/2
minimum = new_value - 2*current

When the operation Push(x) is done, we follow the given below algorithm:

  1. If stack is empty
    1. insert x into the stack
    2. make minimum equal to x.
  2. If stack is not empty
    1. if x is less than minimum
      1. set temp equal to 2*x-minimum
      2. set minimum equal to x
      3. set x equal to temp
    2. insert x into stack

When the operation Pop(x) is done, we follow the given below algorithm:

  1. If stack is not empty
    1. set x equal to topmost element
    2. if x is less than minimum
      1. set minimum equal to 2*minimum – x
      2. set x equal to (x+minimum)/2
    3. return x

When getMin() is called, we return the element stored in variable, minimum:

// Java program to retrieve original elements of the
// from a Stack which returns the minimum element
// in O(1) time and O(1) space

class Stack {
    Node top;

    // Stores minimum element of the stack
    int minimum;
    
    // Function to push an element
    void push(Node node)
    {
        int current = node.getData();
        if (top == null) {
            top = node;
            minimum = current;
        }
        else {
            if (current < minimum) {
                node.setData(2 * current - minimum);
                minimum = current;
            }
            node.setNext(top);
            top = node;
        }
    }

    // Retrieves topmost element
    Node pop()
    {
        Node node = top;
        if (node != null) {
            int current = node.getData();
            if (current < minimum) {
                minimum = 2 * minimum - current;
                node.setData((current + minimum) / 2);
            }
            top = top.getNext();
        }
        return node;
    }

    // Retrieves topmost element without
    // popping it from the stack
    Node peek()
    {
        Node node = null;
        if (top != null) {
            node = new Node();
            int current = top.getData();
            node.setData(current < minimum ? minimum : current);
        }
        return node;
    }

    // Function to print all elements in the stack
    void printAll()
    {
        Node ptr = top;
        int min = minimum;
        if (ptr != null) { // if stack is not empty
            while (true) {
                int val = ptr.getData();
                if (val < min) {
                    min = 2 * min - val;
                    val = (val + min) / 2;
                }
                System.out.print(val + "  ");
                ptr = ptr.getNext();
                if (ptr == null)
                    break;
            }
            System.out.println();
        }
        else
            System.out.println("Empty!");
    }

    // Returns minimum of Stack
    int getMin()
    {
        return minimum;
    }

    boolean isEmpty()
    {
        return top == null;
    }
}

// Node class which contains data
// and pointer to next node
class Node {
    int data;
    Node next;
    Node()
    {
        data = -1;
        next = null;
    }

    Node(int d)
    {
        data = d;
        next = null;
    }

    void setData(int data)
    {
        this.data = data;
    }

    void setNext(Node next)
    {
        this.next = next;
    }

    Node getNext()
    {
        return next;
    }

    int getData()
    {
        return data;
    }
}

// Driver Code
public class Main {
    public static void main(String[] args)
    {
        // Create a new stack
        Stack stack = new Stack();
        Node node;

        // Push the element into the stack
        stack.push(new Node(5));
        stack.push(new Node(3));
        stack.push(new Node(4));

        // Calls the method to print the stack
        System.out.println("Elements in the stack are:");
        stack.printAll();
        
        // Print current minimum element if stack is
        // not empty
        System.out.println(stack.isEmpty() ? "\nEmpty Stack!" : 
                                "\nMinimum: " + stack.getMin());

        // Push new elements into the stack
        stack.push(new Node(1));
        stack.push(new Node(2));

        // Printing the stack
        System.out.println("\nStack after adding new elements:");
        stack.printAll();
        
        // Print current minimum element if stack is
        // not empty
        System.out.println(stack.isEmpty() ? "\nEmpty Stack!" : 
                                    "\nMinimum: " + stack.getMin());

        // Pop elements from the stack
        node = stack.pop();
        System.out.println("\nElement Popped: "
                        + (node == null ? "Empty!" : node.getData()));

        node = stack.pop();
        System.out.println("Element Popped: "
                        + (node == null ? "Empty!" : node.getData()));
        
        // Printing stack after popping elements
        System.out.println("\nStack after removing top two elements:");
        stack.printAll();
        
        // Printing current Minimum element in the stack
        System.out.println(stack.isEmpty() ? "\nEmpty Stack!" : 
                                        "\nMinimum: " + stack.getMin());
        
        // Printing top element of the stack
        node = stack.peek();

        System.out.println("\nTop: " + (node == null ? 
                                       "\nEmpty!" : node.getData()));
    }
}
Output:

Elements in the stack are:
4  3  5  

Minimum: 3

Stack after adding new elements:
2  1  4  3  5  

Minimum: 1

Element Popped: 2
Element Popped: 1

Stack after removing top two elements:
4  3  5  

Minimum: 3

Top: 4


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.




Practice Tags :
Article Tags :

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



0 Average Difficulty : 0/5.0
No votes yet.






User Actions