Showing posts with label stack. Show all posts
Showing posts with label stack. Show all posts

leetcode Question: Implement Queue using Stacks

Implement Queue using Stacks

Implement the following operations of a queue using stacks.
  • push(x) -- Push element x to the back of queue.
  • pop() -- Removes the element from in front of queue.
  • peek() -- Get the front element.
  • empty() -- Return whether the queue is empty.
Notes:

  • You must use only standard operations of a stack -- which means only push to toppeek/pop from topsize, and is empty operations are valid.
  • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
  • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).

Analysis:


This kind of problem usually requires more than one data structure to implement the other data structure. In this problem, two stacks are enough to implement a queue.

The idea is keep push element into stack 1, then "pop" is called, put all the elements from stack 1 to stack 2. Then pop the top element in stack 2.  If "pop" is called again, not stack 2 is not empty, just pop the top element is enough. If stack 2 is empty, put all the elements in stack 1 to stack 2.  In short, stack 1 is used for "push", stack 2 is used for "pop" and "peek". We do the "move element from stack1 to stack 2" only when stack 2 is empty and "pop" or "peek" is called.


e.g., We call push(1), push(2), push(3), push(4), and push(5), stack 1 is filled all the five elements, then do pop(), since stack 2 is empty, move elements from stack 1 to stack 2, then pop the top element (now is 1) in stack2:
 Then we call push(6), push(7), push(8), push(9), and pop(), pop(), pop(), stack 1 is used for pushing, and stack 2 is used for popping :
Again, we call pop() (now 5 is popped out and no element in stack 2), and a peek() operation is called, stack 2 is empty, so push elements from stack 1 to stack 2, and return the top element as the peek:




Code(C++):

class Queue {

stack<int> st1;
stack<int> st2;

public:
    // Push element x to the back of queue.
    void push(int x) {
        st1.push(x);
    }

    // Removes the element from in front of queue.
    void pop(void) {
        if (!st2.empty()){
            st2.pop();
        }else{
            while (!st1.empty()){
                st2.push(st1.top());
                st1.pop();
            }
            st2.pop();
        }
    }

    // Get the front element.
    int peek(void) {
        if (!st2.empty()){
            return st2.top();
        }else{
            while (!st1.empty()){
                st2.push(st1.top());
                st1.pop();
            }
            return st2.top();
        }
    }

    // Return whether the queue is empty.
    bool empty(void) {
        return (st1.empty() && st2.empty());
    }
};

Code(Python):

class Queue(object):
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.st1 = []
        self.st2 = []
        

    def push(self, x):
        """
        :type x: int
        :rtype: nothing
        """
        self.st1.append(x)
        

    def pop(self):
        """
        :rtype: nothing
        """
        if len(self.st2) == 0:
            while len(self.st1) != 0:
                self.st2.append(self.st1.pop())
        self.st2.pop()
                

    def peek(self):
        """
        :rtype: int
        """    
        if len(self.st2) == 0:
            while len(self.st1) != 0:
                self.st2.append(self.st1.pop())
        return self.st2[-1]
        

    def empty(self):
        """
        :rtype: bool
        """
        return not self.st1 and not self.st2


leetcode Question: Basic Calculator

Basic Calculator

Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23

Analysis:

In this question is not difficult but needs to pay more attention on the output order of a stack.
As there might be multiple round brackets (  and  ) in the string, it is natural to use stack to store the chars in the string. Here it doesn't matter to use either one or two stacks. For two stacks, one stores the operators and the other stores the numbers. From the start of the string, we can keep pushing each char into the stack(s),  only when we met the right bracket ")", compute the value of the expression inside "("  and ")", push the value into stack and continue.  When all the chars have been pushed into stack. Check the stacks, we have to continue compute the values according to the operators in stack, until no operators are there.

There are two important points:

  1. Number in the string may not be of length 1, e.g., "123+456".
  2. The output from stack is reverse to the operation order. e.g. for expression 1-2+3, the output from stack is 3, 2, 1 and + , -,   3+2-1 is NOT equal to 1-2+3. 
To handle these issues:
  1. Keep counting the number and push it into stack once we meet operators. Don't forget to push the number when the string ends.
  2. Use temporary stacks to revers the order of expression, then compute the value using correct order.
Let's take an example:

" (1+ (4+5+2)-3)+(6+8)"

1. Keep push the numbers and operators into stacks.


2. When meet the ')', compute the value inside "( )", which is 5+2 = 7, push this value back and continue.

3. Continue the above two steps for the whole string. Compute the rest operations according to the operators inside stack. 

4. The result is the top value in the number stack after all the operations. In this example, after computing 9 + 14 = 23, 23 is the result.


Note that, there might be multiple spaces in the string, an easy way is to get rid of the spaces at the beginning, since spaces is not useful for either operator or numbers.

Code(C++):

class Solution {
public:

    int compute(stack<int> num, stack<char> ops){
        //compute value
        while (!ops.empty()){
            char op = ops.top();
            ops.pop();
            int a = num.top();
            num.pop();
            int b = num.top();
            num.pop();
            if (op == '+'){
                num.push(a+b);
            }else if (op == '-'){
                num.push(a-b);
            }
        }
        return num.top();
    }

    string rmsp(string s){
        string ss = "";
        for (int i=0;i<s.size();i++){
            if (s[i]!=' '){
                ss += s[i];
            }
        }
        return ss;
    }


    int calculate(string s) {
        stack<int> num;
        stack<char> ops;
        
        s = rmsp(s); //remove spaces
        
        int i=0;
        int n = -1;
        while (i<s.size()){
            //current position is a (part of) number
            if (s[i]>='0' && s[i]<='9'){
                if (n==-1){n = 0;}
                n = n * 10 + s[i]-'0';
                i++;
            }else{
                if (n != -1){
                    num.push(n); //push number to stack    
                    n = -1; // set n to zero for new number
                }
                // ) compute value inside round brackets
                if (s[i] == ')'){
                    stack<int> tmp_num;
                    stack<char> tmp_ops;
                    while (ops.top()!='('){
                        tmp_ops.push(ops.top());
                        ops.pop();
                        tmp_num.push(num.top());
                        num.pop();
                    }
                    tmp_num.push(num.top());
                    num.pop();
                    
                    num.push(compute(tmp_num, tmp_ops));
                    ops.pop(); //pop ')' from stack
                    
                } else {
                    ops.push(s[i]);
                }
                i++;
            }
        }
        
        if (n!=-1){
            num.push(n);
        }
        
        stack<int> tmp_num;
        stack<char> tmp_ops;
        while (!ops.empty()){
            tmp_ops.push(ops.top());
            ops.pop();
            tmp_num.push(num.top());
            num.pop();
        }
        tmp_num.push(num.top());
        num.pop();
        
        return compute(tmp_num, tmp_ops);
    }
};

Code(Python):

class Solution(object):
    
    def compute(self, num, ops):
        while len(ops) != 0:
            op = ops.pop()
            if op == '+':
                num.append(num.pop() + num.pop())
            else:
                num.append(num.pop() - num.pop())
        return num[-1]
    
    
    def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        #remove spaces
        s = s.replace(' ', '') 
        
        num = []
        ops = []
        
        i = 0
        n = ''
        while i < len(s):
            if s[i] >= '0' and s[i] <='9':
                n = n + s[i]
                i += 1
            else:
                if n != '':
                    num.append(int(n))
                    n = ''
                
                if s[i] == ')':
                    tmp_num = []
                    tmp_ops = []
                    while ops[-1]!= '(':
                        tmp_ops.append(ops.pop())
                        tmp_num.append(num.pop())
                    tmp_num.append(num.pop())
                    ops.pop()
                    
                    num.append( self.compute(tmp_num, tmp_ops) )
                    
                else:
                    ops.append(s[i])
                    
                i += 1
                
        if n!= '':
            num.append(int(n))

        tmp_num = []
        tmp_ops = []
        while len(ops) != 0:
            tmp_ops.append(ops.pop())
            tmp_num.append(num.pop())
        tmp_num.append(num.pop())
        
                    
        return self.compute(tmp_num, tmp_ops)
            
        


leetcode Question: Implement Stack using Queues

Implement Stack using Queues

Implement the following operations of a stack using queues.
  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • empty() -- Return whether the stack is empty.
Notes:
  • You must use only standard operations of a queue -- which means only push to backpeek/pop from frontsize, and is empty operations are valid.
  • Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
  • You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).

Analysis:

This is a classic question related to queue and stack. Let's review the stack and queue data structure, it is very easy to remember the properties of those two data structures that:

  1. Queue:  FIFO (First In First Out)
  2. Stack: LIFO (Last In First Out)

This question asks to use queue to simulate stack. There are several ways to do so, here I just provide one of the solutions that utilizing two queues. The basic idea is to swap the two queues every time when popping the element from stack. Queue 1 stores the stack top element, Queue 2 stores the previous elements. Every time when pushing one element into stack, push queue 1's top in queue 2, and push the new element in queue 1. Every time when popping the top element in stack, push the queue 1's top (only one element in this queue). Then push n-1 elements from queue 2 to queue 1, where n is the total number of elements in queue 2. In other words, we left one element in queue 2 (this is the top element in the current stack), and push all the other elements into the empty queue (queue 1). Finally we swap queue 1 and queue 2. The stack is empty iff queue 1 and queue 2 are all empty. The top element is always the only element in queue 1.

It is much clear and easier to understand the whole process by reading the code directly. See below for the code in C++ and python.



Code(C++):

class Stack {
private: 
queue<int> q1;
queue<int> q2;

public:
    Stack() {
        queue<int> q1;
        queue<int> q2;
    }
    
    // Push element x onto stack.
    void push(int x) {
        q1.push(x);
        if (q1.size()==1){return;}
        int tmp = q1.front();
        q1.pop();
        q2.push(tmp);
    }

    // Removes the element on top of the stack.
    void pop() {
        q1.pop();
        if (q2.size()==0){return;}
        for (int i=0;i<q2.size()-1; i++){
            q1.push(q2.front());
            q2.pop();
        }
        queue<int> tmp; 
        tmp = q1;
        q1 = q2;
        q2 = tmp;
    }

    // Get the top element.
    int top() {
        return q1.front();
    }

    // Return whether the stack is empty.
    bool empty() {
        if (q1.size()==0 && q2.size()==0){
            return true;
        }else{
            return false;
        }
    }
};

Code(Python):

class Stack(object):
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.q1 = []
        self.q2 = []
        

    def push(self, x):
        """
        :type x: int
        :rtype: nothing
        """
        self.q1.append(x)
        if len(self.q1) == 1:
            return
        else:
            self.q2.append(self.q1.pop(0))
        

    def pop(self):
        """
        :rtype: nothing
        """
        self.q1.pop(0)
        for i in range(len(self.q2)-1):
            self.q1.append(self.q2.pop(0))
        self.q1, self.q2 =  self.q2, self.q1
        

    def top(self):
        """
        :rtype: int
        """
        return self.q1[0]

    def empty(self):
        """
        :rtype: bool
        """
        if len(self.q1)==0 and len(self.q2)==0:
            return True
        else:
            return False

leetcode Question: Min Stack

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.

Analysis:

There are several ways to solve this problem.
(1) Use an extra stack to store the minimum value. The space is O(n), time O(1)
(2) Use a variable to store the minimum value. The time is O(n), space O(1)

Note that, in the python code, a little modification is needed to pass the OJ test.
Just using two stacks is not satisfied with the memory requirement.
So, the min stack stores [min_val, count] instead of each min_val.
e.g.,
Push into Stack:
st     min_st
2      [2,1]

st     min_st
0      [0,1]
2      [2,1]

st     min_st
3    
0      [0,1]
2      [2,1]

st     min_st
0
3    
0      [0,2]
2      [2,1]

Pop:
st     min_st
3    
0      [0,1]
2      [2,1]

st     min_st
0      [0,1]
2      [2,1]

st     min_st
2      [2,1]




Code(C++):


class MinStack {
    deque<int> st;
    int minVal;
public:
    void push(int x) {
        if (st.empty() || x<minVal){
            minVal = x;
        }
        st.push_front(x);
    }

    void pop() {
        if (st.front() == minVal){
            st.pop_front();
            minVal=INT_MAX;
            for (deque<int>::iterator it = st.begin();it!=st.end();it++){
                minVal = min(minVal,*it);
            }
        }else{
            st.pop_front();
        }
        
    }

    int top() {
        return st.front();
    }

    int getMin() {
        return minVal;
    }
};


Code(Python):

class MinStack:
    # @param x, an integer
    # @return an integer
    def __init__(self):
        self.l_num = []
        self.minval = []
    
    def push(self, x):
        if len(self.l_num) == 0 or len(self.minval) == 0:
            self.minval.append([x,1])
        else:
            if x < self.getMin():
                self.minval.append([x,1])
            elif x == self.getMin():
                self.minval[-1][1] += 1
        self.l_num.append(x)
            
    # @return nothing
    def pop(self):
        if self.l_num[-1] == self.minval[-1][0]:
            self.l_num.pop(-1)
            if (self.minval[-1][1]>1):
                self.minval[-1][1] -= 1
            else:
                self.minval.pop(-1)
        else:
            self.l_num.pop(-1)
            
        
    # @return an integer
    def top(self):
        return self.l_num[-1]

    # @return an integer
    def getMin(self):
        return self.minval[-1][0]
        


leetcode Question: Evaluate Reverse Polish Notation

Evaluate Reverse Polish Notation

    Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +-*/. Each operand may be an integer or another expression.
Some examples:
  ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
  ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6


Analysis:


This is a classical algorithm question. The polish notation is the similar to the postorder traversal of the binary tree, and can be efficiently solved using the data structure-----stack.

The concept is:
When meeting the number, push into the stack.
When meeting the operator, pop the top 2 number and compute the value, then push the result back into the stack.
Until the end of the expression.
Output the top (last) value in the stack.

Details can be seen in the code below, there is some points need to be careful with, e.g. the order the the two numbers for the operator.


Code(C++):

class Solution {
public:
    int evalRPN(vector<string> &tokens) {
        stack<int> st;
        string op = "+-*/"; //to check the operator
        if (tokens.size()==0){return 0;}
        for (int i = 0; i<tokens.size();i++){
            string tok = tokens[i];
            int o =op.find(tok); //operator number
            if (o!=-1){
                if (st.size()<2){return -1;}
                else{
                    int a = st.top();
                    st.pop();
                    int b = st.top();
                    st.pop();
                    if (o==0){st.push(b+a);} //remember the order is b -> a
                    if (o==1){st.push(b-a);}
                    if (o==2){st.push(b*a);}
                    if (o==3){st.push(b/a);}
                }
            }else{
                st.push(atoi(tok.c_str()));
            }
        }
        return st.top();
    }
};


Code (Python):


class Solution:
    # @param tokens, a list of string
    # @return an integer
    def evalRPN(self, tokens):
        l=[]
        for str in tokens:
            if (str in ["+","-","*","/"]):
                a = l.pop()
                b = l.pop()
                if (str=="+"):
                    l.append(b+a)
                if (str=="-"):
                    l.append(b-a)
                if (str=="*"):
                    l.append(b*a)
                if (str=="/"):
                    #Be careful! "/" in python is different from C++ 
                    l.append(int(b/(a*1.0)))    
            else:
                l.append(int(str))
        return l[0]