Added notebook solving the following: Implement a queue using two stacks.

This commit is contained in:
Donne Martin 2015-05-22 06:52:41 -04:00
parent 73d265525b
commit 062d27987c
2 changed files with 209 additions and 0 deletions

View File

@ -38,6 +38,7 @@ Continually updated IPython Notebooks containing coding problems and solutions (
* [Implement a stack that keeps track of its minimum element](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/stack-min.ipynb) * [Implement a stack that keeps track of its minimum element](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/stack-min.ipynb)
* [Implement a set of stacks class that wraps a list of stacks, each bound by a capacity](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/set-of-stacks.ipynb) * [Implement a set of stacks class that wraps a list of stacks, each bound by a capacity](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/set-of-stacks.ipynb)
* [Implement the Towers of Hanoi with 3 towers and N disks](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/hanoi.ipynb) * [Implement the Towers of Hanoi with 3 towers and N disks](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/hanoi.ipynb)
* [Implement a queue using two stacks](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/queue-from-stacks.ipynb)
## Hacker Rank ## Hacker Rank

View File

@ -0,0 +1,208 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Implement a queue using two stacks.\n",
"\n",
"* [Clarifying Questions](#Clarifying-Questions)\n",
"* [Test Cases](#Test-Cases)\n",
"* [Algorithm](#Algorithm)\n",
"* [Code](#Code)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Clarifying Questions\n",
"\n",
"* Do you expect the methods to be enqueue and dequeue?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"* Enqueue and dequeue on empty stack\n",
"* Enqueue and dequeue on non-empty stack\n",
"* Multiple enqueue in a row\n",
"* Multiple dequeue in a row\n",
"* Enqueue after a dequeue\n",
"* Dequeue after an enqueue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"We'll use two stacks (left and right) to implement the queue. The left stack will be used for enqueue and the right stack will be used for dequeue.\n",
"\n",
"To prevent multiple dequeue calls from needlessly shifting elements around between the stacks, we'll shift elements in a lazy manner.\n",
"\n",
"### Enqueue\n",
"\n",
"* If the left stack is empty and the right stack is not empty\n",
" * Shift the elements of the right stack to the left stack\n",
"* Push the data to the left stack\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(n)\n",
"\n",
"### Dequeue\n",
"\n",
"* If the right stack is empty and the the left stack is not empty\n",
" * Shift the elements of the left stack to the right stack\n",
"* Pop from the right stack and return the data\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(n)\n",
"\n",
"### Shift Stacks\n",
"\n",
"* While the source stack has elements:\n",
" * Pop from the source stack and push the data to the destination stack\n",
"\n",
"Complexity:\n",
"* Time: O(n)\n",
"* Space: O(1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%run stack.py"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class QueueFromStacks(object):\n",
" def __init__(self):\n",
" self.left_stack = Stack()\n",
" self.right_stack = Stack()\n",
"\n",
" def is_stack_empty(self, stack):\n",
" return stack.peek() is None\n",
"\n",
" def shift_stacks(self, source, destination):\n",
" while source.peek() is not None:\n",
" destination.push(source.pop())\n",
"\n",
" def enqueue(self, data):\n",
" if self.is_stack_empty(self.left_stack) and not self.is_stack_empty(self.right_stack):\n",
" self.shift_stacks(self.right_stack, self.left_stack)\n",
" self.left_stack.push(data)\n",
"\n",
" def dequeue(self):\n",
" if self.is_stack_empty(self.right_stack) and not self.is_stack_empty(self.left_stack):\n",
" self.shift_stacks(self.left_stack, self.right_stack)\n",
" return self.right_stack.pop()"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dequeue on empty stack\n",
"None\n",
"Enqueue on empty stack\n",
"Enqueue on non-empty stack\n",
"Multiple enqueue in a row\n",
"Dequeue on non-empty stack\n",
"Dequeue after an enqueue\n",
"0\n",
"Multiple dequeue in a row\n",
"1\n",
"2\n",
"Enqueue after a dequeue\n",
"5\n",
"None\n"
]
}
],
"source": [
"print('Dequeue on empty stack')\n",
"queue = QueueFromStacks()\n",
"print(queue.dequeue())\n",
"print('Enqueue on empty stack')\n",
"print('Enqueue on non-empty stack')\n",
"print('Multiple enqueue in a row')\n",
"num_items = 3\n",
"for i in range (0, num_items):\n",
" queue.enqueue(i)\n",
"print('Dequeue on non-empty stack')\n",
"print('Dequeue after an enqueue')\n",
"print(queue.dequeue())\n",
"print('Multiple dequeue in a row')\n",
"print(queue.dequeue())\n",
"print(queue.dequeue())\n",
"print('Enqueue after a dequeue')\n",
"queue.enqueue(5)\n",
"print(queue.dequeue())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.9"
}
},
"nbformat": 4,
"nbformat_minor": 0
}