forked from keon/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f76c34b
Showing
34 changed files
with
1,541 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Pythonic Data Structures and Algorithms | ||
|
||
Minimal and clean examples of data structures and algorithms. | ||
|
||
|
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
def append_to_sequence (myseq): | ||
myseq += (9,9,9) | ||
return myseq | ||
|
||
tuple1 = (1,2,3) # tuples are immutable | ||
list1 = [1,2,3] # lists are mutable | ||
|
||
tuple2 = append_to_sequence(tuple1) | ||
list2 = append_to_sequence(list1) | ||
|
||
print 'tuple1 = ', tuple1 # outputs (1, 2, 3) | ||
print 'tuple2 = ', tuple2 # outputs (1, 2, 3, 9, 9, 9) | ||
print 'list1 = ', list1 # outputs [1, 2, 3, 9, 9, 9] | ||
print 'list2 = ', list2 # outputs [1, 2, 3, 9, 9, 9] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
myGraph = {'A': ['B', 'C'], | ||
'B': ['C', 'D'], | ||
'C': ['D', 'F'], | ||
'D': ['C'], | ||
'E': ['F'], | ||
'F': ['C']} | ||
|
||
# find path from start to end using recursion with backtracking | ||
def find_path(graph, start, end, path=[]): | ||
path = path + [start] | ||
if (start == end): | ||
return path | ||
if not start in graph: | ||
return None | ||
for node in graph[start]: | ||
if node not in path: | ||
newpath = find_path(graph, node, end, path) | ||
return newpath | ||
return None | ||
|
||
# find all path | ||
def find_all_path(graph, start, end, path=[]): | ||
path = path + [start] | ||
print(path) | ||
if (start == end): | ||
return [path] | ||
if not start in graph: | ||
return None | ||
paths = [] | ||
for node in graph[start]: | ||
if node not in path: | ||
newpaths = find_all_path(graph, node, end, path) | ||
for newpath in newpaths: | ||
paths.append(newpath) | ||
return paths | ||
|
||
|
||
def find_shortest_path(graph, start, end, path=[]): | ||
path = path + [start] | ||
if start == end: | ||
return path | ||
if start not in graph: | ||
return None | ||
shortest = None | ||
for node in graph[start]: | ||
if node not in path: | ||
newpath = find_shortest_path(graph, start, end, path) | ||
if newpath: | ||
if not shortest or len(newpath) < len(shortest): | ||
shortest = newpath | ||
return shortest | ||
|
||
print(find_all_path(myGraph, 'A', 'F')) | ||
# print(find_shortest_path(myGraph, 'A', 'D')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class Graph: | ||
def __init__(self, node, edges, source): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
graph = {'A': set(['B', 'C', 'F']), | ||
'B': set(['A', 'D', 'E']), | ||
'C': set(['A', 'F']), | ||
'D': set(['B']), | ||
'E': set(['B', 'F']), | ||
'F': set(['A', 'C', 'E'])} | ||
|
||
# dfs and bfs are the ultimately same except that they are visiting nodes in | ||
# different order. To simulate this ordering we would use stack for dfs and | ||
# queue for bfs. | ||
# | ||
|
||
def dfs_traverse(graph, start): | ||
visited, stack = set(), [start] | ||
while stack: | ||
node = stack.pop() | ||
if node not in visited: | ||
visited.add(node) | ||
for nextNode in graph[node]: | ||
if nextNode not in visited: | ||
stack.append(nextNode) | ||
return visited | ||
|
||
# print(dfs_traverse(graph, 'A')) | ||
|
||
|
||
def bfs_traverse(graph, start): | ||
visited, queue = set(), [start] | ||
while queue: | ||
node = queue.pop(0) | ||
if node not in visited: | ||
visited.add(node) | ||
for nextNode in graph[node]: | ||
if nextNode not in visited: | ||
queue.append(nextNode) | ||
return visited | ||
|
||
# print(bfs_traverse(graph, 'A')) | ||
|
||
def dfs_traverse_recursive(graph, start, visited=None): | ||
if visited is None: | ||
visited = set() | ||
visited.add(start) | ||
for nextNode in graph[start]: | ||
if nextNode not in visited: | ||
dfs_traverse_recursive(graph, nextNode, visited) | ||
return visited | ||
|
||
# print(dfs_traverse_recursive(graph, 'A')) | ||
|
||
# def find_path(graph, start, end, visited=[]): | ||
# # basecase | ||
# visitied = visited + [start] | ||
# if start == end: | ||
# return visited | ||
# if start not in graph: | ||
# return None | ||
# for node in graph[start]: | ||
# if node not in visited: | ||
# new_visited = find_path(graph, node, end, visited) | ||
# return new_visited | ||
# return None | ||
|
||
# print(find_path(graph, 'A', 'F')) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# MAP Abstract Data Type | ||
# Map() Create a new, empty map. It returns an empty map collection. | ||
# put(key,val) Add a new key-value pair to the map. If the key is already in the map then replace the old value with the new value. | ||
# get(key) Given a key, return the value stored in the map or None otherwise. | ||
# del Delete the key-value pair from the map using a statement of the form del map[key]. | ||
# len() Return the number of key-value pairs stored in the map. | ||
# in Return True for a statement of the form key in map, if the given key is in the map, False otherwise. | ||
|
||
class HashTable(object): | ||
def __init__(self, size = 11): | ||
self.size = size | ||
self.keys = [None] * size # keys | ||
self.values = [None] * size # values | ||
|
||
def put(self, key, value): | ||
hashval = self.hash(key) | ||
|
||
if hashval not in keys: | ||
self.keys[hashval] = key | ||
self.values[hashval] = value | ||
else: | ||
if self.keys[hashval] == key: # replace | ||
self.values[hashval] = value | ||
else: # probing | ||
rehashval = self.rehash(key) | ||
while self.keys[rehashval] is not None and \ | ||
self.keys[rehashval] != key: | ||
rehashval = self.rehash(rehashval) | ||
if keys[rehashval] is None: | ||
self.keys[rehashval] = key | ||
self.values[rehashval] = value | ||
else: | ||
self.values[rehashval] = value # replacee | ||
|
||
def get(self, key): | ||
pass | ||
|
||
def hash(self, key): | ||
return key % self.size | ||
|
||
def rehash(self, oldhash): | ||
""" | ||
linear probing | ||
""" | ||
return (oldhash + 1) % self.size | ||
|
||
def __getitem__(self,key): | ||
return self.get(key) | ||
|
||
def __setitem__(self, key, value): | ||
self.put(key, value) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Pros | ||
# Linked Lists have constant-time insertions and deletions in any position, | ||
# in comparison, arrays require O(n) time to do the same thing. | ||
# Linked lists can continue to expand without having to specify | ||
# their size ahead of time (remember our lectures on Array sizing | ||
# form the Array Sequence section of the course!) | ||
|
||
# Cons | ||
# To access an element in a linked list, you need to take O(k) time | ||
# to go from the head of the list to the kth element. | ||
# In contrast, arrays have constant time operations to access | ||
# elements in an array. | ||
|
||
class DoublyLinkedList(object): | ||
def __init__(self, value): | ||
self.value = value | ||
self.next = None | ||
self.prev = None | ||
|
||
|
||
class SinglyLinkedList(object): | ||
def __init__(self, value): | ||
self.value = value | ||
self.next = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# def lengthLongestPath(input): | ||
# maxlen = 0 | ||
# pathlen = {0: 0} | ||
# for line in input.splitlines(): | ||
# print("---------------") | ||
# print("line:", line) | ||
# name = line.strip('\t') | ||
# print("name:", name) | ||
# depth = len(line) - len(name) | ||
# print("depth:", depth) | ||
# if '.' in name: | ||
# maxlen = max(maxlen, pathlen[depth] + len(name)) | ||
# else: | ||
# pathlen[depth + 1] = pathlen[depth] + len(name) + 1 | ||
# print("maxlen:", maxlen) | ||
# return maxlen | ||
|
||
# def lengthLongestPath(input): | ||
# paths = input.split("\n") | ||
# level = [0] * 10 | ||
# maxLength = 0 | ||
# for path in paths: | ||
# print("-------------") | ||
# levelIdx = path.rfind("\t") | ||
# print("Path: ", path) | ||
# print("path.rfind(\\t)", path.rfind("\t")) | ||
# print("levelIdx: ", levelIdx) | ||
# print("level: ", level) | ||
# level[levelIdx + 1] = level[levelIdx] + len(path) - levelIdx + 1 | ||
# print("level: ", level) | ||
# if "." in path: | ||
# maxLength = max(maxLength, level[levelIdx+1] - 1) | ||
# print("maxlen: ", maxLength) | ||
# return maxLength | ||
|
||
def lengthLongestPath(input): | ||
""" | ||
:type input: str | ||
:rtype: int | ||
""" | ||
currlen, maxlen = 0, 0 # running length and max length | ||
stack = [] # keep track of the name length | ||
for s in input.split('\n'): | ||
print("---------") | ||
print("<path>:", s) | ||
depth = s.count('\t') # the depth of current dir or file | ||
print("depth: ", depth) | ||
print("stack: ", stack) | ||
print("curlen: ", currlen) | ||
while len(stack) > depth: # go back to the correct depth | ||
currlen -= stack.pop() | ||
stack.append(len(s.strip('\t'))+1) # 1 is the length of '/' | ||
currlen += stack[-1] # increase current length | ||
print("stack: ", stack) | ||
print("curlen: ", currlen) | ||
if '.' in s: # update maxlen only when it is a file | ||
maxlen = max(maxlen, currlen-1) # -1 is to minus one '/' | ||
return maxlen | ||
|
||
st= "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdirectory1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" | ||
st2 = "a\n\tb1\n\t\tf1.txt\n\taaaaa\n\t\tf2.txt" | ||
print("path:", st2) | ||
|
||
print("answer:", lengthLongestPath(st2)) | ||
|
Oops, something went wrong.