# Implement a queue with two stacks

(HackerRank exercise.)

In this implementation of a queue the dequeue operation will have average-case time complexity `O(1)` but worst-case time complexity `O(n)`. So there are better ways to implement a queue. The idea is to use one list as an inbox and the other as an outbox. The key tactic to implement this idea is that reversing a stack amounts to popping each element and appending it to a new stack:

```def rev_stack(stk):
out_stk = []
while stk:
ele = stk.pop()
out_stk.append(ele)
return out_stk
```

which in the abstract arises from the fact that a stack has the first-in-last-out property. So the algorithm as a whole is:

• maintain two stacks: call them in_stack and out_stack
• enqueue: append the new item to the in_stack (`O(1)` worst case)
• dequeue: pop an item from the out_stack then if the out_stack has now become empty pop the elements of the in_stack one by one and append them onto the out_stack (`O(n)` worst-case but `O(1)` average-case)

and note that the last bullet contains the operation `rev_stack` as described above. In total we have:

```class MyQueue(object):
def __init__(self):
self.instack = []
self.outstack = []

def peek(self):
out = self.outstack[-1]
return out

def shuffle(self):
if not self.outstack:
while self.instack:
ele = self.instack.pop()
self.outstack.append(ele)

def pop(self):
out = self.outstack.pop()
self.shuffle()
return out

def put(self, value):
self.instack.append(value)
```

where we have written `enqueue` as `put` and `dequeue` as `pop`.