Saturday, July 09, 2016

Min Stack

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.
Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> Returns -3.
minStack.pop();
minStack.top();      --> Returns 0.
minStack.getMin();   --> Returns -2. 
 
I had a dumb simple implementation which is slow.
 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class MinStack {
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
Stack<Integer> s = new Stack<Integer>();
    /** initialize your data structure here. */
    public MinStack() {
        
    }
    
    public void push(int x) {
        s.push(x);
        pq.add(x);
    }
    
    public void pop() {
        int tmp = s.peek();
        s.pop();
        pq.remove(tmp);
    }
    
    public int top() {
        return s.peek();
    }
    
    public int getMin() {
        return pq.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */
Then a better one. just store min with number
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class MinStack {
    Stack<Integer> s = new Stack<Integer>();
    int min = Integer.MIN_VALUE;
    public MinStack() {
        // do initialize if necessary
    }

    public void push(int number) {
        // write your code here
        if(s.isEmpty() ||number <min){
            min = number;
        }
       
        s.push(number);
        s.push(min);
    }

    public int pop() {
        // write your code here
        int num;
        if(s.isEmpty()){
            min= Integer.MIN_VALUE;
            num = min;
        }else{
            s.pop();//pop out min
            num = s.pop();
            if(s.isEmpty()){
                min= Integer.MIN_VALUE;
            }
            else{
                min = s.peek();
            }
        }
        return num;
    }

    public int min() {
        // write your code here
        return min;
    }
}

But This is how smart guys do. Use only one stack, but duplicate store the min value when minimum changes.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class MinStack {
    int min=Integer.MAX_VALUE;
    Stack<Integer> stack = new Stack<Integer>();
    public void push(int x) {
       // only push the old minimum value when the current 
       // minimum value changes after pushing the new value x
        if(x <= min){          
            stack.push(min);
            min=x;
        }
        stack.push(x);
    }

    public void pop() {
       // if pop operation could result in the changing of the current minimum value, 
       // pop twice and change the current minimum value to the last minimum value.
        if(stack.peek()==min) {
            stack.pop();
            min=stack.peek();
            stack.pop();
        }else{
            stack.pop();
        }
        if(stack.empty()){
            min=Integer.MAX_VALUE;
        }
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return min;
    }
}

No comments: