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:

- If stack is empty

- insert x into the stack
- make minimum equal to x.
- If stack is not empty

- if x is less than minimum

- set temp equal to 2*x-minimum
- set minimum equal to x
- set x equal to temp
- insert x into stack

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

- If stack is not empty

- set x equal to topmost element
- if x is less than minimum

- set minimum equal to 2*minimum – x
- set x equal to (x+minimum)/2
- 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

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.