From a5d58e2728bade310288f3da91b48dc7a1cbfeea Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Sun, 17 May 2015 07:41:32 -0400 Subject: [PATCH] Added notebook solving the following: Implement SetOfStacks that wraps a list of stacks, where each stack is bound by a capacity. --- README.md | 1 + stacks-queues/set-of-stacks.ipynb | 191 ++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 stacks-queues/set-of-stacks.ipynb diff --git a/README.md b/README.md index 32119af..6e30a33 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Continually updated IPython Notebooks containing coding problems and solutions ( * [Implement a queue with enqueue and dequeue methods using a linked list](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/queue.ipynb) * [Implement n stacks using a single array](http://nbviewer.ipython.org/github/donnemartin/algorithms-data-structures/blob/master/stacks-queues/n-stacks.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 SetOfStacks 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) ## License diff --git a/stacks-queues/set-of-stacks.ipynb b/stacks-queues/set-of-stacks.ipynb new file mode 100644 index 0000000..537c21b --- /dev/null +++ b/stacks-queues/set-of-stacks.ipynb @@ -0,0 +1,191 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Implement SetOfStacks that wraps a set of stacks bound by a capacity.\n", + "\n", + "* [Clarifying Questions](#Clarifying-Questions)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Pythonic-Code](#Pythonic-Code)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Clarifying Questions\n", + "\n", + "* Can we assume we have a Stack class to use?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* Push and pop on an empty stack\n", + "* Push and pop on a non-empty stack\n", + "* Push on a capacity stack to create a new one\n", + "* Pop on a one element stack to destroy it" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "### Push\n", + "\n", + "* If there are no stacks or the last stack is full\n", + " * Create a new stack\n", + "* Push to the new stack\n", + "\n", + "Complexity:\n", + "* Time: O(1)\n", + "* Space: O(1)\n", + "\n", + "### Pop\n", + "\n", + "* If there are no stacks, return None\n", + "* Else if the last stack has one element\n", + " * Pop the last element's data\n", + " * Delete the now empty stack\n", + " * Update the last stack pointer\n", + "* Else Pop the last element's data\n", + "* Return the last element's data\n", + "\n", + "Complexity:\n", + "* Time: O(1)\n", + "* Space: O(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "%run stack.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class StackWithCapacity(Stack):\n", + " def __init__(self, top=None, capacity=10):\n", + " self.capacity = capacity\n", + " self.num_items = 0\n", + " super(StackWithCapacity, self).__init__(top)\n", + "\n", + " def push(self, data):\n", + " if self.num_items < self.capacity:\n", + " super(StackWithCapacity, self).push(data)\n", + " self.num_items += 1\n", + " else:\n", + " raise Exception('Stack full')\n", + "\n", + " def pop(self):\n", + " data = super(StackWithCapacity, self).pop()\n", + " self.num_items -= 1\n", + " return data\n", + "\n", + " def is_full(self):\n", + " return self.num_items == self.capacity\n", + "\n", + "class SetOfStacks(object):\n", + " def __init__(self, capacity):\n", + " self.capacity = capacity\n", + " self.stacks = []\n", + " self.last_stack = None\n", + "\n", + " def push(self, data):\n", + " if self.last_stack is None or self.last_stack.is_full():\n", + " self.last_stack = StackWithCapacity(None, self.capacity)\n", + " self.stacks.append(self.last_stack)\n", + " self.last_stack.push(data)\n", + "\n", + " def pop(self):\n", + " if self.last_stack is None:\n", + " return\n", + " elif self.last_stack.top.next is None:\n", + " data = self.last_stack.pop()\n", + " self.stacks.pop()\n", + " num_stacks = len(self.stacks)\n", + " if num_stacks == 0:\n", + " self.last_stack = None\n", + " else:\n", + " self.last_stack = self.stacks[num_stacks-1]\n", + " else:\n", + " data = self.last_stack.pop()\n", + " return data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print('Push on an empty stack')\n", + "capacity = 2\n", + "stacks = SetOfStacks(capacity)\n", + "stacks.push(3)\n", + "print('Push on a non-empty stack')\n", + "stacks.push(5)\n", + "print('Push on a capacity stack to create a new one')\n", + "stacks.push('a')\n", + "print('Pop on a one element stack to destroy it')\n", + "print(stacks.pop())\n", + "print('Pop general case')\n", + "print(stacks.pop())\n", + "print(stacks.pop())\n", + "print('Pop on no elements')\n", + "print(stacks.pop())" + ] + } + ], + "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 +}