Python Algorithm Q24

Q24 Implement Queue using Stacks


Q

Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push, peek, pop, and empty).

Implement the MyQueue class:

  • void push(int x) Pushes element x to the back of the queue.
  • int pop() Removes the element from the front of the queue and returns it.
  • int peek() Returns the element at the front of the queue.
  • boolean empty() Returns true if the queue is empty, false otherwise.

Notes:

  • You must use only standard operations of a stack, which means only push to top, peek/pop from top, size, and is empty operations are valid.
  • Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack’s standard operations.

Sample Input

Input
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]

Explanation
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

Constraints

  • 1 <= x <= 9
  • At most 100 calls will be made to push, pop, peek, and empty.
  • All the calls to pop and peek are valid.

1. My Solution

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
class MyQueue:

    def __init__(self):
        #def myque with the type stack
        self.q = []

    def push(self, x: int) -> None:
        self.q.append(x)

    def pop(self) -> int:
        self.q.reverse()
        pop = self.q.pop()
        self.q.reverse()
        return pop

    def peek(self) -> int:
        self.q.reverse()
        head = self.q.pop()
        self.q.append(head)
        self.q.reverse()
        return head
        
    def empty(self) -> bool:
        if self.q:
            return False
        else:
            return True
        

obj = MyQueue()
obj.push(1)
print(obj.q)
obj.push(2)
print(obj.q)
print(obj.peek())
obj.pop()
print(obj.q)
print(obj.empty())

Nothing Special. Using basic method of stacks(push and pop), implementing queue is not that hard. Just reverse the stack list.
But my answer takes so much time to execute than others. Need to modify peek function to improve the performance.

2. Given Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MyQueue:

    def __init__(self):
        self.input = []
        self.output = []

    def push(self, x: int) -> None:
        self.input.append(x)

    def pop(self) -> int:
        self.peek()
        return self.output.pop()

    def peek(self) -> int:
        #output이 없으면 모두 재입력
        if not self.output:
            while self.input:
                self.output.append(self.input.pop())
        return self.output[-1]
        
    def empty(self) -> bool:
        return self.input == [] and self.output == []

In the Q23, we used self.q.append(self.q.popleft()), so do pop & append simultaneously. However, in this problem, we only have the method ‘pop’. That drag (last) values from the list. So this code end up looping infinitely. Therefore introduce one more list.

Input list is only for the input. All the values is only appended to the ‘input’ list. In contrast, output list is only for the output by pop method. The function ‘pop’ pop values from the output list.

When you call pop or peek function, Send input list to output list in reversed order. Refill output list only when output list is empty.

3. Given Solution

This is just for reference… This sol used searching method of python-list. However, this answer takes the least runtime.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyQueue:

    def __init__(self):
        self.stack = []

    def push(self, x: int) -> None:
        self.stack.append(x)

    def pop(self) -> int:
        a = self.stack[0]
        del self.stack[0]
        return a

    def peek(self) -> int:
        return self.stack[0]

    def empty(self) -> bool:
        if len(self.stack):
            return False
        else:
            return True


Overall Review

Considering execution time is quiet complicated. My own solution works well, but takes much more time than other submissions. I think reverse() method use up some time.