I'm wondering if it is possible to implement a queue using two stacks so that each queue operation takes amortized constant time.
I'm wondering if it is possible to implement a queue using two stacks so that each queue operation takes amortized constant time.
class QQ:
def __init__(self):
self.s = []
self.ss = []
def enque(self, val):
self.s.append(val)
def deque(self):
if not self.s and not self.ss: return None
if not self.ss:
while self.s:
self.ss.append(self.s.pop())
return self.ss.pop()
The second stack ss holds the content of the first stack s in reverse order when we pop the elements of s into ss. A reversed stack is just a queue. Whenever ss is empty, we load all elements in s into ss. If it isn't empty we just deque one element from it.
The time complexity is amortized constant since we make only one move to enqueing and in the long run only 2 moves for dequeing.
We use 2 stacks with tags "front" and "back".
In front stack we should use size and clear methods, which size returns stack's pointer, and clear sets pointer to 0.
For enqueue(), we should push new element to front stack. So the time-complexity will be O(1).
For dequeue(), if back stack is empty, we should fill it with elements that are in front stack, for every element that is inside the front stack we should call pop() function and then use push() function to insert it in back stack, since we know the size of front stack (and it is constant) and pop and push function have time-complexity of O(1), the whole complexity of dequeue will be O(1).
For size(), it will return the sum of front and back stacks size().
For isEmpty() it should return if the size is equal to zero or not.