some interview problems

This commit is contained in:
Mari Wahl 2014-10-27 10:12:15 -04:00
parent 899a11e9ad
commit 0f559fa0d7
10 changed files with 533 additions and 0 deletions

View File

@ -0,0 +1,25 @@
class Queue():
def __init__(self):
self.in_ = []
self.out = []
def enqueue(self, item):
self.in_.append(item)
def deque(self):
if not self.out:
while self.in_:
self.out.append(self.in_.pop())
return self.out.pop()
q = Queue()
for i in range(10):
q.enqueue(i)
for i in range(10):
print(q.deque())

View File

@ -0,0 +1,9 @@
Another way:
Store two stacks, one of which contains all of the items in the stack and one of which is a stack of minima.
To push an element, push it onto the first stack. Check whether it is smaller than the top item on the second stack, if so, push it onto the second stack.
To pop an item, pop it from the first stack. If it is the top element, simply return the element on the top of the second stack.
O(1)...

View File

@ -0,0 +1,33 @@
BITWISE
----------------------
1. To find a number:
11000101 is 2^0+2^2+2^6+2^7 = 197
2. Left shifting:
0010 1011 << 4 ---> 1011 000
3. Right shifting:
0010 1011 >> 4 ---> 0000 0010
or it can be filled with the copy of the first bit, instead of 0:
1011 0010 >> 4 ---> 1111 1011
4. XOR can cancels out:
15 ^ 12 ^ 15 = 12
5. 2^x:
left-shift 1 by x:
0000 0001 << x
so if x = 2, 2^2 = 4 -> 100
0000 0001 << 2 ---> 0000 0100
6. Is power of 2?
just do x&(x-1).
if 0 --> yes!

View File

@ -0,0 +1,21 @@
DESIGN PATTERNS
------------------------
LISTENER/OBSERVER:
-----------------
- Example: a GUI as a listener to several objects. For any change in the state, it would update the display.
SINGLETON PATTERN:
-----------------
- To make sure that there is exactly one instance of something in the program.
MODEL-VIEW-CONTROLLER:
----------------------
- Design commonly used in user interfaces. The goal is to keep the data separate from the interface.
- Separate programming entities to store the data (model), display the data (view) and modify the data (controlle).
- The view usually makes heavy use of listeners to listen to changes and events in the model or controller.

View File

@ -0,0 +1,8 @@
DESIGN A TEXT EDITOR
-------------------------------------
- Classes to set up the text editor: classes for the GUI, formatting, saving/loading files, handling input.
- Use inheritance where it makes sense.
- Use design patterns (such as MVC, listener, singleton).

View File

@ -0,0 +1,73 @@
#!/usr/bin/python
__author__ = "bt3"
__email__ = "bt33gl@gmail.com"
from binary_tree import NodeBT, BinaryTree
class NodeBST(NodeBT):
def __init__(self, item=None, level=0):
self.item = item
self.level = level
self.left = None
self.right = None
def _addNextNode(self, value, level_here=1):
new_node = NodeBST(value, level_here)
if not self.item:
self.item = new_node
else:
if value > self.item:
self.right = self.right and self.right._addNextNode(value, level_here+1) or new_node
elif value < self.item:
self.left = self.left and self.left._addNextNode(value, level_here+1) or new_node
else:
print("BSTs do not support repeated items.")
return self # this is necessary!!!
def _searchForNode(self, value):
if self.item == value:
return self
elif self.left and value < self.item:
return self.left._searchForNode(value)
elif self.right and value > self.item:
return self.right._searchForNode(value)
else:
return False
class BinarySearchTree(BinaryTree):
def __init__(self):
self.root = None
def addNode(self, value):
if not self.root:
self.root = NodeBST(value)
else:
self.root._addNextNode(value)
if __name__ == '__main__':
bst = BinarySearchTree()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10):
bst.addNode(i)
print "Is 8 a leaf? ", bst.isLeaf(8)
print "Whats the level of node 8? ", bst.getNodeLevel(8)
print "Is node 10 a root? ", bst.isRoot(10)
print "Is node 1 a root? ", bst.isRoot(1)
print "Whats the tree height? ", bst.getHeight()
print "Is this tree BST? ", bst.isBST()
print "Is this tree balanced? ", bst.isBalanced()

View File

@ -0,0 +1,206 @@
#!/usr/bin/python
__author__ = "bt3"
__email__ = "bt33gl@gmail.com"
''' Implementation of a binary tree and its properties. For example, the following bt:
1 ---> level 0
2 3 ---> level 1
4 5 ---> level 2
6 7 ---> level 3
8 9 ---> level 4
has the following properties:
- SIZE OR NUMBER OF NODES: n = 9
- NUMBER OF BRANCHES OR INTERNAL NODES: b = n-1 = 8
- VALUE OF ROOT = 1
- MAX_DEPTH OR HEIGHT: h = 4
- IS BALANCED? NO
- IS BST? NO
'''
class NodeBT(object):
def __init__(self, item=None, level=0):
self.item = item
self.level = level
self.left = None
self.right = None
def __repr__(self):
return '{}'.format(self.item)
def _addNextNode(self, value, level_here=1):
new_node = NodeBT(value, level_here)
if not self.item:
self.item = new_node
elif not self.left:
self.left = new_node
elif not self.right:
self.right = new_node
else:
self.left = self.left._addNextNode(value, level_here+1)
return self ## this is important, because the node return to the main
def _searchForNode(self, value):
if self.item == value:
return self
else:
found = None
if self.left:
found = self.left._searchForNode(value)
if self.right:
found = found or self.right._searchForNode(value)
return found
def _isLeaf(self):
return not self.right and not self.left
def _getMaxHeight(self):
''' Get the max height at the node, O(n)'''
levelr, levell = 0, 0
if self.right:
levelr = self.right._getMaxHeight() + 1
if self.left:
levell = self.left._getMaxHeight() + 1
return max(levelr, levell)
def _getMinHeight(self, level=0):
''' Get the min height at the node, O(n)'''
levelr, levell = -1, -1
if self.right:
levelr = self.right._getMinHeight(level +1)
if self.left:
levell = self.left._getMinHeight(level +1)
return min(levelr, levell) + 1
def _isBalanced(self):
''' Find whether the tree is balanced, by calculating heights first, O(n2) '''
if self._getMaxHeight() - self._getMinHeight() < 2:
return False
else:
if self._isLeaf():
return True
elif self.left and self.right:
return self.left._isBalanced() and self.right._isBalanced()
elif not self.left and self.right:
return self.right._isBalanced()
elif not self.right and self.left:
return self.left._isBalanced()
def _isBST(self, mintree=None, maxtree=None):
''' Find whether the tree is a BST, inorder '''
if self.item:
if not mintree:
mintree = self.item
if not maxtree:
maxtree = self.item
if self._isLeaf():
return True
elif self.left:
if self.left.item < self.item and mintree > self.left.item:
mintree = self.left.item
return self.left._isBST(mintree, maxtree)
else:
return False
elif self.right:
if self.right.item > self.item and maxtree < self.right.item:
maxtree = self.right.item
return self.right._isBST(mintree, maxtree)
else:
return False
else:
print('Tree is empty')
class BinaryTree(object):
def __init__(self):
self.root = None
def addNode(self, value):
if not self.root:
self.root = NodeBT(value)
else:
self.root._addNextNode(value)
def isLeaf(self, value):
node = self.root._searchForNode(value)
if node:
return node._isLeaf()
else:
print "Node not found."
def getNodeLevel(self, item):
node = self.root._searchForNode(item)
if node:
return node.level
else:
print('Node not found')
def isRoot(self, value):
return self.root.item == value
def getHeight(self):
return self.root._getMaxHeight()
def isBalanced(self):
return self.root._isBalanced()
def isBST(self):
return self.root._isBST()
def preorder(self):
current = self.root
nodes, stack = [], []
while stack or current:
if current:
nodes.append(current.item) # thats what change
stack.append(current)
current = current.left
else:
current = stack.pop()
current = current.right
return nodes
if __name__ == '__main__':
bt = BinaryTree()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10):
bt.addNode(i)
print "Is 8 a leaf? ", bt.isLeaf(8)
print "Whats the level of node 8? ", bt.getNodeLevel(8)
print "Is node 10 a root? ", bt.isRoot(10)
print "Is node 1 a root? ", bt.isRoot(1)
print "Whats the tree height? ", bt.getHeight()
print "Is this tree BST? ", bt.isBST()
print "Is this tree balanced? ", bt.isBalanced()
print (bt.preorder())

View File

@ -0,0 +1,65 @@
__author__ = "bt3"
__email__ = "bt33gl@gmail.com"
""" need to keep track of min and max!!!"""
from binary_tree import BinaryTree, NodeBT
from binary_search_tree import BinarySearchTree, NodeBST
## my solution
def isBST(bt, mintree=None, maxtree=None):
if not bt.item:
return True
if not mintree:
mintree = bt.item
if not maxtree:
maxtree = bt.item
left, right = False, False
if bt.left:
if bt.left.item > bt.item and bt.left.item < mintree:
return False
else:
mintree = bt.left.item
left = isBST(bt.left, mintree, maxtree)
else:
left = True
if bt.right:
if bt.right.item < bt.item and bt.right.item > maxtree:
return False
else:
maxtree = bt.right.item
right = isBST(bt.right, mintree, maxtree)
else:
right = True
return left or right
if __name__ == '__main__':
bt = BinaryTree()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10):
bt.addNode(i)
print(isBST(bt.root))
bst = BinarySearchTree()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10):
bst.addNode(i)
print(isBST(bst.root))
print(bst.isBST())

View File

@ -0,0 +1,48 @@
#!/usr/bin/python
__author__ = "bt3"
__email__ = "bt33gl@gmail.com"
from binary_tree import BinaryTree
def inorder(node, path=None):
if node:
path = path or []
path.append(node.item)
inorder(node.left, path)
inorder(node.right, path)
return path
def lowest_commom_ancestor(node, node1, node2):
path = inorder(node.root)
i1, i2 = 0, 0
for i,n in enumerate(path):
if n == node1:
i1 = i
if n == node2:
i2 = i
return path[i1:i2+1]
if __name__ == '__main__':
bt = BinaryTree()
l = [10, 6, 14, 3, 7, 11, 15]
for i in l:
bt.addNode(i)
print(l)
print(lowest_commom_ancestor(bt, 10, 6))
print(lowest_commom_ancestor(bt, 10, 14))
print(lowest_commom_ancestor(bt, 10, 3))
print(lowest_commom_ancestor(bt, 10, 7))
print(lowest_commom_ancestor(bt, 10, 11))
print(lowest_commom_ancestor(bt, 10, 15))

View File

@ -0,0 +1,45 @@
#!/usr/bin/python
__author__ = "bt3"
__email__ = "bt33gl@gmail.com"
''' find the lowest ancestor in a BST '''
from transversal_BST_recursively import BSTwithTransversalRecursively
def find_ancestor(path, low_value, high_value):
while path:
current_value = path[0]
if current_value < low_value:
try:
path = path[2:]
except:
return current_value
elif current_value > high_value:
try:
path = path[1:]
except:
return current_value
elif low_value <= current_value <= high_value:
return current_value
else:
return None # this is probably never touched
if __name__ == '__main__':
bst = BSTwithTransversalRecursively()
l = [10, 5, 15, 1, 6, 11, 50]
for i in l:
bst.addNode(i)
path = bst.preorder()
print("The path inorder: ", path)
print("The path between 1 and 6 is :", find_ancestor(path, 1, 6))
print("The path between 1 and 11 is: ", find_ancestor(path, 1, 11))
print("The path between 11 and 50 is: ", find_ancestor(path, 11, 50))
print("The path between 5 and 15 is: ", find_ancestor(path, 5, 15))