design a stack such that getMinimum( ) should be O(1)

Viewed 116312

This is an interview question.

You need to design a stack which holds an integer value such that getMinimum() function should return the minimum element in the stack.

For example:

case #1

5 ← TOP
1
4
6
2

When getMinimum() is called it should return 1, which is the minimum element in the stack.

case #2

stack.pop()
stack.pop()

Note: Both 5 and 1 are popped out of the stack. So after this, the stack looks like

4 ← TOP
6
2

When getMinimum() is called it should return 2 which is the minimum in the stack.

Constraints:

  1. getMinimum should return the minimum value in O(1)
  2. Space constraint also has to be considered while designing it and if you use extra space, it should be of constant space.
31 Answers

EDIT: This fails the "constant space" constraint - it basically doubles the space required. I very much doubt that there's a solution which doesn't do that though, without wrecking the runtime complexity somewhere (e.g. making push/pop O(n)). Note that this doesn't change the complexity of the space required, e.g. if you've got a stack with O(n) space requirements, this will still be O(n) just with a different constant factor.

Non-constant-space solution

Keep a "duplicate" stack of "minimum of all values lower in the stack". When you pop the main stack, pop the min stack too. When you push the main stack, push either the new element or the current min, whichever is lower. getMinimum() is then implemented as just minStack.peek().

So using your example, we'd have:

Real stack        Min stack

5  --> TOP        1
1                 1
4                 2
6                 2
2                 2

After popping twice you get:

Real stack        Min stack

4                 2
6                 2
2                 2

Please let me know if this isn't enough information. It's simple when you grok it, but it might take a bit of head-scratching at first :)

(The downside of course is that it doubles the space requirement. Execution time doesn't suffer significantly though - i.e. it's still the same complexity.)

EDIT: There's a variation which is slightly more fiddly, but has better space in general. We still have the min stack, but we only pop from it when the value we pop from the main stack is equal to the one on the min stack. We only push to the min stack when the value being pushed onto the main stack is less than or equal to the current min value. This allows duplicate min values. getMinimum() is still just a peek operation. For example, taking the original version and pushing 1 again, we'd get:

Real stack        Min stack

1  --> TOP        1
5                 1
1                 2
4                 
6                 
2                 

Popping from the above pops from both stacks because 1 == 1, leaving:

Real stack        Min stack

5  --> TOP        1
1                 2
4                 
6                 
2                 

Popping again only pops from the main stack, because 5 > 1:

Real stack        Min stack

1                 1
4                 2
6                 
2                 

Popping again pops both stacks because 1 == 1:

Real stack        Min stack

4                 2
6                 
2                 

This ends up with the same worst case space complexity (double the original stack) but much better space usage if we rarely get a "new minimum or equal".

EDIT: Here's an implementation of Pete's evil scheme. I haven't tested it thoroughly, but I think it's okay :)

using System.Collections.Generic;

public class FastMinStack<T>
{
    private readonly Stack<T> stack = new Stack<T>();
    // Could pass this in to the constructor
    private readonly IComparer<T> comparer = Comparer<T>.Default;

    private T currentMin;

    public T Minimum
    {
        get { return currentMin; }
    }

    public void Push(T element)
    {
        if (stack.Count == 0 ||
            comparer.Compare(element, currentMin) <= 0)
        {
            stack.Push(currentMin);
            stack.Push(element);
            currentMin = element;
        }
        else
        {
            stack.Push(element);
        }
    }

    public T Pop()
    {
        T ret = stack.Pop();
        if (comparer.Compare(ret, currentMin) == 0)
        {
            currentMin = stack.Pop();
        }
        return ret;
    }
}

Add a field to hold the minimum value and update it during Pop() and Push(). That way getMinimum() will be O(1), but Pop() and Push() will have to do a little more work.

If minimum value is popped, Pop() will be O(n), otherwise they will still both be O(1). When resizing Push() becomes O(n) as per the Stack implementation.

Here's a quick implementation

public sealed class MinStack {
    private int MinimumValue;
    private readonly Stack<int> Stack = new Stack<int>();

    public int GetMinimum() {
        if (IsEmpty) {
            throw new InvalidOperationException("Stack is empty");
        }
        return MinimumValue;
    }

    public int Pop() {
        var value = Stack.Pop();
        if (value == MinimumValue) {
            MinimumValue = Stack.Min();
        }
        return value;
    }

    public void Push(int value) {
        if (IsEmpty || value < MinimumValue) {
            MinimumValue = value;
        }
        Stack.Push(value);
    }

    private bool IsEmpty { get { return Stack.Count() == 0; } }
}
public class StackWithMin {
    int min;
    int size;
    int[] data = new int[1024];

    public void push ( int val ) {
        if ( size == 0 ) {
            data[size] = val;
            min = val;
        } else if ( val < min) {
            data[size] = 2 * val - min;
            min = val;

            assert (data[size] < min); 
        } else {
            data[size] = val;
        }

        ++size;

        // check size and grow array
    }

    public int getMin () {
        return min;
    }

    public int pop () {
        --size;

        int val = data[size];

        if ( ( size > 0 ) && ( val < min ) ) {
            int prevMin = min;
            min += min - val;
            return prevMin;
        } else {
            return val;
        }
    }

    public boolean isEmpty () {
        return size == 0;
    }

    public static void main (String...args) {
        StackWithMin stack = new StackWithMin();

        for ( String arg: args ) 
            stack.push( Integer.parseInt( arg ) );

        while ( ! stack.isEmpty() ) {
            int min = stack.getMin();
            int val = stack.pop();

            System.out.println( val + " " + min );
        }

        System.out.println();
    }

}

It stores the current minimum explicitly, and if the minimum changes, instead of pushing the value, it pushes a value the same difference the other side of the new minimum ( if min = 7 and you push 5, it pushes 3 instead ( 5-|7-5| = 3) and sets min to 5; if you then pop 3 when min is 5 it sees that the popped value is less than min, so reverses the procedure to get 7 for the new min, then returns the previous min). As any value which doesn't cause a change the current minimum is greater than the current minimum, you have something that can be used to differentiate between values which change the minimum and ones which don't.

In languages which use fixed size integers, you're borrowing a bit of space from the representation of the values, so it may underflow and the assert will fail. But otherwise, it's constant extra space and all operations are still O(1).

Stacks which are based instead on linked lists have other places you can borrow a bit from, for example in C the least significant bit of the next pointer, or in Java the type of the objects in the linked list. For Java this does mean there's more space used compared to a contiguous stack, as you have the object overhead per link:

public class LinkedStackWithMin {
    private static class Link {
        final int value;
        final Link next;

        Link ( int value, Link next ) {
            this.value = value;
            this.next = next;
        }

        int pop ( LinkedStackWithMin stack ) {
            stack.top = next;
            return value;
        }
    }

    private static class MinLink extends Link {
        MinLink ( int value, Link next ) {
            super( value, next );
        }

        int pop ( LinkedStackWithMin stack ) {
            stack.top = next;
            int prevMin = stack.min;
            stack.min = value;
            return prevMin;
        }
    }

    Link top;
    int min;

    public LinkedStackWithMin () {
    }

    public void push ( int val ) {
        if ( ( top == null ) || ( val < min ) ) {
            top = new MinLink(min, top);
            min = val;
        } else {
            top = new Link(val, top);
        }
    }

    public int pop () {
        return top.pop(this);
    }

    public int getMin () {
        return min;
    }

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

In C, the overhead isn't there, and you can borrow the lsb of the next pointer:

typedef struct _stack_link stack_with_min;

typedef struct _stack_link stack_link;

struct _stack_link {
    size_t  next;
    int     value;
};

stack_link* get_next ( stack_link* link ) 
{
    return ( stack_link * )( link -> next & ~ ( size_t ) 1 );
}

bool is_min ( stack_link* link )
{
    return ( link -> next & 1 ) ! = 0;
}

void push ( stack_with_min* stack, int value )
{
    stack_link *link = malloc ( sizeof( stack_link ) );

    link -> next = ( size_t ) stack -> next;

    if ( (stack -> next == 0) || ( value == stack -> value ) ) {
        link -> value = stack -> value;
        link -> next |= 1; // mark as min
    } else {
        link -> value = value;
    }

    stack -> next = link;
}

etc.;

However, none of these are truly O(1). They don't require any more space in practice, because they exploit holes in the representations of numbers, objects or pointers in these languages. But a theoretical machine which used a more compact representation would require an extra bit to be added to that representation in each case.

Well, what are the runtime constraints of push and pop? If they are not required to be constant, then just calculate the minimum value in those two operations (making them O(n)). Otherwise, I don't see how this can be done with constant additional space.

Let's assume the stack which we will be working on is this :

6 , minvalue=2
2 , minvalue=2
5 , minvalue=3
3 , minvalue=3
9 , minvalue=7
7 , minvalue=7
8 , minvalue=8

In the above representation the stack is only built by left value's the right value's [minvalue] is written only for illustration purpose which will be stored in one variable.

The actual problem is when the value which is the minimum value gets removed: At that point how can we know what is the next minimum element without iterating over the stack.

Like for example in our stack when 6 gets popped we know that, this is not the minimum element because the minimum element is 2, so we can safely remove this without updating our min value.

But when we pop 2, we can see that the minimum value is 2 right now and if this gets popped out then we need to update the minimum value to 3.

Point1:

Now if you observe carefully we need to generate minvalue=3 from this particular state [2 , minvalue=2].
Or if you go deeper in the stack we need to generate minvalue=7 from this particular state [3 , minvalue=3]
or if you go deeper still in the stack then we need to generate minvalue=8 from this particular state [7 , minvalue=7]

Did you notice something in common in all of the above three cases? The value which we need to generate depends upon two variable which are both equal. Correct.
Why is this happening because when we push some element smaller then the current minvalue, then we basically push that element in the stack and updated the same number in minvalue also.

Point2:

So we are basically storing duplicate of the same number once in stack and once in minvalue variable.
We need to focus on avoiding this duplication and store something useful data in the stack or the minvalue to generate the previous minimum as shown in CASES above.

Let's focus on what should we store in stack when the value to store in push is less than the minimum value. Let's name this variable y, so now our stack will look something like this:

6 , minvalue=2
y1 , minvalue=2
5 , minvalue=3
y2 , minvalue=3
9 , minvalue=7
y3 , minvalue=7
8 , minvalue=8

I have renamed them as y1,y2,y3 to avoid confusion that all of them will have same value.

Point3:

Now let's try to find some constraint's over y1, y2 and y3. Do you remember when exactly we need to update the minvalue while doing pop(), only when we have popped the element which is equal to the minvalue.
If we pop something greater than the minvalue then we don't have to update minvalue.
So to trigger the update of minvalue, y1,y2&y3 should be smaller than there corresponding minvalue. [We are avoiding equality to avoid duplicate[Point2]]
so the constrain is [ y < minValue ].

Now let's come back to populate y, we need to generate some value and put y at the time of push, remember.
Let's take the value which is coming for push to be x which is less that the prevMinvalue, and the value which we will actually push in stack to be y.
So one thing is obvious that the newMinValue=x, and y < newMinvalue.

Now we need to calculate y(remember y can be any number which is less than newMinValue(x) so we need to find some number which can fulfil our constraint) with the help of prevMinvalue and x(newMinvalue).

Let's do the math:
    x < prevMinvalue [Given]
    x - prevMinvalue < 0 
    x - prevMinValue + x < 0 + x [Add x on both side]
    2*x - prevMinValue < x      
this is the y which we were looking for less than x(newMinValue).
y = 2*x - prevMinValue. 'or' y = 2*newMinValue - prevMinValue 'or' y = 2*curMinValue - prevMinValue [taking curMinValue=newMinValue].

So at the time of pushing x if it is less than prevMinvalue then we push y[2*x-prevMinValue] and update newMinValue = x .

And at the time of pop if the stack contains something less than the minValue then that's our trigger to update the minValue. We have to calculate prevMinValue from the curMinValue and y.
  y = 2*curMinValue - prevMinValue [Proved]
  prevMinValue = 2*curMinvalue - y .

2*curMinValue - y is the number which we need to update now to the prevMinValue.

Code for the same logic is shared below with O(1) time and O(1) space complexity.

// C++ program to implement a stack that supports 
// getMinimum() in O(1) time and O(1) extra space. 
#include <bits/stdc++.h> 
using namespace std; 
  
// A user defined stack that supports getMin() in 
// addition to push() and pop() 
struct MyStack 
{ 
    stack<int> s; 
    int minEle; 
  
    // Prints minimum element of MyStack 
    void getMin() 
    { 
        if (s.empty()) 
            cout << "Stack is empty\n"; 
  
        // variable minEle stores the minimum element 
        // in the stack. 
        else
            cout <<"Minimum Element in the stack is: "
                 << minEle << "\n"; 
    } 
  
    // Prints top element of MyStack 
    void peek() 
    { 
        if (s.empty()) 
        { 
            cout << "Stack is empty "; 
            return; 
        } 
  
        int t = s.top(); // Top element. 
  
        cout << "Top Most Element is: "; 
  
        // If t < minEle means minEle stores 
        // value of t. 
        (t < minEle)? cout << minEle: cout << t; 
    } 
  
    // Remove the top element from MyStack 
    void pop() 
    { 
        if (s.empty()) 
        { 
            cout << "Stack is empty\n"; 
            return; 
        } 
  
        cout << "Top Most Element Removed: "; 
        int t = s.top(); 
        s.pop(); 
  
        // Minimum will change as the minimum element 
        // of the stack is being removed. 
        if (t < minEle) 
        { 
            cout << minEle << "\n"; 
            minEle = 2*minEle - t; 
        } 
  
        else
            cout << t << "\n"; 
    } 
  
    // Removes top element from MyStack 
    void push(int x) 
    { 
        // Insert new number into the stack 
        if (s.empty()) 
        { 
            minEle = x; 
            s.push(x); 
            cout <<  "Number Inserted: " << x << "\n"; 
            return; 
        } 
  
        // If new number is less than minEle 
        if (x < minEle) 
        { 
            s.push(2*x - minEle); 
            minEle = x; 
        } 
  
        else
           s.push(x); 
  
        cout <<  "Number Inserted: " << x << "\n"; 
    } 
}; 
  
// Driver Code 
int main() 
{ 
    MyStack s; 
    s.push(3); 
    s.push(5); 
    s.getMin(); 
    s.push(2); 
    s.push(1); 
    s.getMin(); 
    s.pop(); 
    s.getMin(); 
    s.pop(); 
    s.peek(); 
  
    return 0; 
} 

Here is my version of implementation.

 struct MyStack {
    int element;
    int *CurrentMiniAddress;
 };

 void Push(int value)
 {
    // Create you structure and populate the value
    MyStack S = new MyStack();
    S->element = value;

    if(Stack.Empty())
    {    
        // Since the stack is empty, point CurrentMiniAddress to itself
        S->CurrentMiniAddress = S;

    }
    else
    {
         // Stack is not empty

         // Retrieve the top element. No Pop()
         MyStack *TopElement = Stack.Top();

         // Remember Always the TOP element points to the
         // minimum element in ths whole stack
         if (S->element CurrentMiniAddress->element)
         {
            // If the current value is the minimum in the whole stack
            // then S points to itself
            S->CurrentMiniAddress = S;
         }
             else
             {
                 // So this is not the minimum in the whole stack
                 // No worries, TOP is holding the minimum element
                 S->CurrentMiniAddress = TopElement->CurrentMiniAddress;
             }

    }
        Stack.Add(S);
 }

 void Pop()
 {
     if(!Stack.Empty())
     {
        Stack.Pop();
     }  
 }

 int GetMinimum(Stack &stack)
 {
       if(!stack.Empty())
       {
            MyStack *Top  = stack.top();
            // Top always points to the minimumx
            return  Top->CurrentMiniAddress->element;
        }
 }
    **The task can be acheived by creating two stacks:**



import java.util.Stack;
    /*
     * 
     * Find min in stack using O(n) Space Complexity
     */
    public class DeleteMinFromStack {

        void createStack(Stack<Integer> primary, Stack<Integer> minStack, int[] arr) {
    /* Create main Stack and in parallel create the stack which contains the minimum seen so far while creating main Stack */
            primary.push(arr[0]);
            minStack.push(arr[0]);

            for (int i = 1; i < arr.length; i++) {
                primary.push(arr[i]);
                if (arr[i] <= minStack.peek())// Condition to check to push the value in minimum stack only when this urrent value is less than value seen at top of this stack */
                    minStack.push(arr[i]);
            }

        }

        int findMin(Stack<Integer> secStack) {
            return secStack.peek();
        }

        public static void main(String args[]) {

            Stack<Integer> primaryStack = new Stack<Integer>();
            Stack<Integer> minStack = new Stack<Integer>();

            DeleteMinFromStack deleteMinFromStack = new DeleteMinFromStack();

            int[] arr = { 5, 5, 6, 8, 13, 1, 11, 6, 12 };
            deleteMinFromStack.createStack(primaryStack, minStack, arr);
            int mimElement = deleteMinFromStack.findMin(primaryStack, minStack);
    /** This check for algorithm when the main Stack Shrinks by size say i as in loop below */
            for (int i = 0; i < 2; i++) {
                primaryStack.pop();
            }

            System.out.println(" Minimum element is " + mimElement);
        }

    }
/*
here in have tried to add for loop wherin the main tack can be shrinked/expaned so we can check the algorithm */

A practical implementation for finding minimum in a Stack of User Designed Object, named: School

The Stack is going to store the Schools in Stack based on the rank assigned to a school in specific region, say, findMin() gives the School where we get the maximum number of applications for Admissions, which in turn is to be defined by the comparator which uses rank associated with the schools in previous season .

The Code for same is below:


   package com.practical;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class CognitaStack {

    public School findMin(Stack<School> stack, Stack<School> minStack) {

        if (!stack.empty() && !minStack.isEmpty())
            return (School) minStack.peek();
        return null;
    }

    public School removeSchool(Stack<School> stack, Stack<School> minStack) {

        if (stack.isEmpty())
            return null;
        School temp = stack.peek();
        if (temp != null) {
            // if(temp.compare(stack.peek(), minStack.peek())<0){
            stack.pop();
            minStack.pop();
            // }

            // stack.pop();
        }
        return stack.peek();
    }

    public static void main(String args[]) {

        Stack<School> stack = new Stack<School>();
        Stack<School> minStack = new Stack<School>();

        List<School> lst = new LinkedList<School>();

        School s1 = new School("Polam School", "London", 3);
        School s2 = new School("AKELEY WOOD SENIOR SCHOOL", "BUCKINGHAM", 4);
        School s3 = new School("QUINTON HOUSE SCHOOL", "NORTHAMPTON", 2);
        School s4 = new School("OAKLEIGH HOUSE SCHOOL", " SWANSEA", 5);
        School s5 = new School("OAKLEIGH-OAK HIGH SCHOOL", "Devon", 1);
        School s6 = new School("BritishInter2", "Devon", 7);

        lst.add(s1);
        lst.add(s2);
        lst.add(s3);
        lst.add(s4);
        lst.add(s5);
        lst.add(s6);

        Iterator<School> itr = lst.iterator();
        while (itr.hasNext()) {
            School temp = itr.next();
            if ((minStack.isEmpty()) || (temp.compare(temp, minStack.peek()) < 0)) { // minStack.peek().equals(temp)
                stack.push(temp);
                minStack.push(temp);
            } else {
                minStack.push(minStack.peek());
                stack.push(temp);
            }

        }

        CognitaStack cogStack = new CognitaStack();
        System.out.println(" Minimum in Stack is " + cogStack.findMin(stack, minStack).name);
        cogStack.removeSchool(stack, minStack);
        cogStack.removeSchool(stack, minStack);

        System.out.println(" Minimum in Stack is "
                + ((cogStack.findMin(stack, minStack) != null) ? cogStack.findMin(stack, minStack).name : "Empty"));
    }

}

Also the School Object is as follows:

package com.practical;

import java.util.Comparator;

public class School implements Comparator<School> {

    String name;
    String location;
    int rank;

    public School(String name, String location, int rank) {
        super();
        this.name = name;
        this.location = location;
        this.rank = rank;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((location == null) ? 0 : location.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + rank;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        School other = (School) obj;
        if (location == null) {
            if (other.location != null)
                return false;
        } else if (!location.equals(other.location))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (rank != other.rank)
            return false;
        return true;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public int compare(School o1, School o2) {
        // TODO Auto-generated method stub
        return o1.rank - o2.rank;
    }

}

class SchoolComparator implements Comparator<School> {

    public int compare(School o1, School o2) {
        return o1.rank - o2.rank;
    }

}

This Example covers the following: 1. Implementation of Stack for User defined Objects, here, School 2. Implementation for the hashcode() and equals() method using all fields of Objects to be compared 3. A practical implementation for the scenario where we rqeuire to get the Stack contains operation to be in order of O(1)

Here is my solution in java using liked list.

class Stack{
    int min;
    Node top;
    static class Node{
        private int data;
        private Node next;
        private int min;

        Node(int data, int min){
           this.data = data;
           this.min = min;
           this.next = null; 
    }
}

  void push(int data){
        Node temp;
        if(top == null){
            temp = new Node(data,data);
            top = temp;
            top.min = data;
        }
        if(top.min > data){
            temp = new Node(data,data);
            temp.next = top;
            top = temp;
        } else {
            temp = new Node(data, top.min);
            temp.next = top;
            top = temp;
        }
  }

  void pop(){
    if(top != null){
        top = top.next;
    }
  }

  int min(){
    return top.min;
  }

}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Solution 
{
    public class MinStack
    {
        public MinStack()
        {
            MainStack=new Stack<int>();
            Min=new Stack<int>();
        }

        static Stack<int> MainStack;
        static Stack<int> Min;

        public void Push(int item)
        {
            MainStack.Push(item);

            if(Min.Count==0 || item<Min.Peek())
                Min.Push(item);
        }

        public void Pop()
        {
            if(Min.Peek()==MainStack.Peek())
                Min.Pop();
            MainStack.Pop();
        }
        public int Peek()
        {
            return MainStack.Peek();
        }

        public int GetMin()
        {
            if(Min.Count==0)
                throw new System.InvalidOperationException("Stack Empty"); 
            return Min.Peek();
        }
    }
}

Saw a brilliant solution here: https://www.geeksforgeeks.org/design-a-stack-that-supports-getmin-in-o1-time-and-o1-extra-space/

Bellow is the python code I wrote by following the algorithm:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class MinStack:
    def __init__(self):
        self.head = None
        self.min = float('inf')

    # @param x, an integer
    def push(self, x):
        if self.head == None:
            self.head = Node(x)
            self.min = x
        else:
            if x >= self.min:
                n = Node(x)
                n.next = self.head
                self.head = n
            else:
                v = 2 * x - self.min
                n = Node(v)
                n.next = self.head
                self.head = n
                self.min = x

    # @return nothing
    def pop(self):
        if self.head:
            if self.head.value < self.min:
                self.min = self.min * 2 - self.head.value
            self.head = self.head.next

    # @return an integer
    def top(self):
        if self.head:
            if self.head.value < self.min:
                self.min = self.min * 2 - self.head.value
                return self.min
            else:
                return self.head.value
        else:
            return -1

    # @return an integer
    def getMin(self):
        if self.head:
            return self.min
        else:
            return -1

To getMin elements from Stack. We have to use Two stack .i.e Stack s1 and Stack s2.

  1. Initially, both stacks are empty, so add elements to both stacks

---------------------Recursively call Step 2 to 4-----------------------

  1. if New element added to stack s1.Then pop elements from stack s2

  2. compare new elments with s2. which one is smaller , push to s2.

  3. pop from stack s2(which contains min element)

Code looks like:

package Stack;
import java.util.Stack;
public class  getMin 
{  

        Stack<Integer> s1= new Stack<Integer>();
        Stack<Integer> s2 = new Stack<Integer>();

        void push(int x)
        {
            if(s1.isEmpty() || s2.isEmpty())

            {
                 s1.push(x);
                 s2.push(x);
            }
            else
            {

               s1. push(x);
                int y = (Integer) s2.pop();
                s2.push(y);
                if(x < y)
                    s2.push(x);
                        }
        }
        public Integer pop()
        {
            int x;
            x=(Integer) s1.pop();
            s2.pop();
            return x;

        }
    public  int getmin()
        {
            int x1;
            x1= (Integer)s2.pop();
            s2.push(x1);
            return x1;
        }

    public static void main(String[] args) {
        getMin s = new getMin();
            s.push(10);
            s.push(20);
            s.push(30);
            System.out.println(s.getmin());
            s.push(1);
            System.out.println(s.getmin());
        }

}

I have better solution, with O(1) time and with no extra space, You need to push element as String as <original_value,minimum_value>. For example find this stack of string.

|-1,-1 |

| 1,1 |

| 2,2 |

| 5,3 |

| 3,3 |


Now u can always find min value at current instance by just using peek and checking what is min value at the given instance. this is O(1) time without extra space

Related