├── .gitignore ├── linked_list ├── __init__.py ├── p0.py ├── p1.py ├── p2.py ├── p3.py ├── p4.py ├── p5.py └── p6.py └── stacks_queues ├── __init__.py ├── p0.py ├── p1.py ├── p2.py ├── p3.py └── p4.py /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python ### 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | .DS_store 8 | -------------------------------------------------------------------------------- /linked_list/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kojino/data-structures-algorithms/4ba684dfbd95e3b98e3590fa9d0127c537233a5b/linked_list/__init__.py -------------------------------------------------------------------------------- /linked_list/p0.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P0. Implement a linked list 3 | ''' 4 | class Node: 5 | def __init__(self,val): 6 | self.val = val 7 | self.next = None # the pointer initially points to nothing 8 | -------------------------------------------------------------------------------- /linked_list/p1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P1. Traverse a linked list 3 | ''' 4 | import p0 5 | 6 | class Node(p0.Node): 7 | def traverse(self): 8 | node = self 9 | while node != None: 10 | print node.val 11 | node = node.next 12 | 13 | if __name__ == "__main__": 14 | node1 = Node(1) 15 | node2 = Node(2) 16 | node3 = Node(3) 17 | node4 = Node(1) 18 | node1.next = node2 19 | node2.next = node3 20 | node3.next = node4 21 | 22 | node1.traverse() 23 | -------------------------------------------------------------------------------- /linked_list/p2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P2. Remove duplicates from a linked list 3 | ''' 4 | 5 | 6 | import p1 7 | 8 | class Node(p1.Node): 9 | def remove_duplicates(self): 10 | els = [] 11 | node = self 12 | previous = None 13 | while node != None: 14 | if node.val in els: 15 | previous.next = node.next 16 | else: 17 | els.append(node.val) 18 | previous = node 19 | node = node.next 20 | 21 | if __name__ == "__main__": 22 | node1 = Node(1) 23 | node2 = Node(2) 24 | node3 = Node(3) 25 | node4 = Node(1) 26 | node1.next = node2 27 | node2.next = node3 28 | node3.next = node4 29 | 30 | node1.remove_duplicates() 31 | node1.traverse() 32 | -------------------------------------------------------------------------------- /linked_list/p3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P3. Get the kth to last element from a linked list 3 | ''' 4 | 5 | 6 | import p1 7 | 8 | class Node(p1.Node): 9 | def kth_to_last(self,k): 10 | if k < 0: 11 | return None 12 | p1 = self 13 | p2 = self 14 | i = -1 15 | while p1 != None: 16 | p1 = p1.next 17 | if i < k: 18 | i += 1 19 | else: 20 | p2 = p2.next 21 | if i == k: 22 | return p2.val 23 | else: 24 | return None 25 | 26 | if __name__ == "__main__": 27 | node1 = Node(1) 28 | node2 = Node(2) 29 | node3 = Node(3) 30 | node4 = Node(1) 31 | node1.next = node2 32 | node2.next = node3 33 | node3.next = node4 34 | 35 | print node1.kth_to_last(2) 36 | print node1.kth_to_last(-10) 37 | -------------------------------------------------------------------------------- /linked_list/p4.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P4. Delete a node from a linked list 3 | ''' 4 | 5 | 6 | import p1 7 | 8 | class Node(p1.Node): 9 | def delete_node(self): 10 | node = self 11 | if node == None or node.next == None: 12 | return False 13 | node.val = node.next.val 14 | node.next = node.next.next 15 | return True 16 | 17 | if __name__ == "__main__": 18 | node1 = Node(1) 19 | node2 = Node(2) 20 | node3 = Node(3) 21 | node4 = Node(1) 22 | node1.next = node2 23 | node2.next = node3 24 | node3.next = node4 25 | 26 | node2.delete_node() 27 | node1.traverse() 28 | -------------------------------------------------------------------------------- /linked_list/p5.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P5. Add two linked lists from left to right 3 | e.g. 1->2->3 + 8->7 => 321+78 = 399 4 | ''' 5 | from p1 import Node 6 | 7 | def sum_linked_lists_backword(p1, p2): 8 | carry_over = 0 9 | head = Node(0) 10 | pointer = head 11 | digit = 0 12 | # until both linked lists exist, sum elements 13 | while p1 != None and p2 != None: 14 | sum_ = p1.val + p2.val + carry_over 15 | pointer.next = Node(sum_ % 10) 16 | pointer = pointer.next 17 | carry_over = sum_ / 10 18 | p1 = p1.next 19 | p2 = p2.next 20 | 21 | if p1 == None: 22 | while p2 != None: 23 | sum_ = p2.val + carry_over 24 | pointer.next = Node(sum_ % 10) 25 | pointer = pointer.next 26 | carry_over = sum_ / 10 27 | p2 = p2.next 28 | 29 | if p2 == None: 30 | while p1 != None: 31 | sum_ = p1.val + carry_over 32 | pointer.next = Node(sum_ % 10) 33 | pointer = pointer.next 34 | carry_over = sum_ / 10 35 | p1 = p1.next 36 | if carry_over > 0: 37 | pointer.next = Node(carry_over) 38 | return head.next 39 | 40 | if __name__ == "__main__": 41 | node1 = Node(1) 42 | node2 = Node(2) 43 | node3 = Node(3) 44 | node4 = Node(9) 45 | node5 = Node(8) 46 | node6 = Node(7) 47 | node1.next = node2 48 | node2.next = node3 49 | node4.next = node5 50 | node5.next = node6 51 | 52 | sum1 = sum_linked_lists_backword(node1,node4) # 321 + 789 = 1110 53 | sum2 = sum_linked_lists_backword(node1,node5) # 321 + 78 = 399 54 | sum1.traverse() 55 | sum2.traverse() 56 | -------------------------------------------------------------------------------- /linked_list/p6.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P6. Add two linked lists from right to left 3 | e.g. 1->2->3 + 8->7 => 123+87 = 210 4 | ''' 5 | import p1 6 | 7 | class Node(p1.Node): 8 | def length(self): 9 | length = 1 10 | node = self 11 | while node != None: 12 | node = node.next 13 | length += 1 14 | return length 15 | 16 | def pad_zeros(n,node): 17 | head = node 18 | for i in range(n): 19 | node0 = Node(0) 20 | node0.next = head 21 | head = node0 22 | return head 23 | 24 | def sum_linked_lists_forward(p1,p2): 25 | p1_len = p1.length() 26 | p2_len = p2.length() 27 | if p1_len > p2_len: 28 | p2 = pad_zeros(p1_len - p2_len, p2) 29 | elif p2_len > p1_len: 30 | p1 = pad_zeros(p2_len - p1_len, p1) 31 | result,carry_over = sum_linked_lists_forward_helper(p1,p2) 32 | if carry_over > 0: 33 | new_node = Node(carry_over) 34 | new_node.next = result 35 | return new_node 36 | return result 37 | 38 | def sum_linked_lists_forward_helper(p1,p2,): 39 | if p1 == None and p2 == None: 40 | return None,0 41 | else: 42 | result,carry_over = sum_linked_lists_forward_helper(p1.next,p2.next) 43 | sum_ = p1.val + p2.val + carry_over 44 | new_node = Node(sum_%10) 45 | new_node.next = result 46 | return new_node,sum_/10 47 | 48 | if __name__ == "__main__": 49 | node1 = Node(1) 50 | node2 = Node(2) 51 | node3 = Node(3) 52 | node4 = Node(9) 53 | node5 = Node(8) 54 | node6 = Node(7) 55 | node1.next = node2 56 | node2.next = node3 57 | node4.next = node5 58 | node5.next = node6 59 | # sum1 = sum_linked_lists_forward(node1,node4) # 123 + 987 = 1110 60 | sum2 = sum_linked_lists_forward(node1,node5) # 123 + 87 = 210 61 | # sum1.traverse() 62 | sum2.traverse() 63 | -------------------------------------------------------------------------------- /stacks_queues/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kojino/data-structures-algorithms/4ba684dfbd95e3b98e3590fa9d0127c537233a5b/stacks_queues/__init__.py -------------------------------------------------------------------------------- /stacks_queues/p0.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P0. Implement a stack 3 | ''' 4 | class Stack: 5 | def __init__(self): 6 | self.stack = [] 7 | 8 | def pop(self): 9 | if self.is_empty(): 10 | return None 11 | else: 12 | return self.stack.pop() 13 | 14 | def push(self,val): 15 | return self.stack.append(val) 16 | 17 | def peak(self): 18 | if self.is_empty(): 19 | return None 20 | else: 21 | return self.stack[-1] 22 | 23 | def size(self): 24 | return len(self.stack) 25 | 26 | def is_empty(self): 27 | return self.size() == 0 28 | -------------------------------------------------------------------------------- /stacks_queues/p1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | P1. Implement a queue 3 | ''' 4 | class Queue: 5 | def __init__(self): 6 | self.queue = [] 7 | 8 | def enqueue(self,val): 9 | self.queue.insert(0,val) 10 | 11 | def dequeue(self): 12 | if self.is_empty(): 13 | return None 14 | else: 15 | return self.queue.pop() 16 | 17 | def size(self): 18 | return len(self.queue) 19 | 20 | def is_empty(self): 21 | return self.size() == 0 22 | -------------------------------------------------------------------------------- /stacks_queues/p2.py: -------------------------------------------------------------------------------- 1 | from p0 import Stack 2 | 3 | ''' 4 | Given a string of brackets, determine if the string is balanced 5 | 6 | Sample Input 7 | {[()]} 8 | {[(])} 9 | {{[[(())]]}} 10 | 11 | Sample Output 12 | YES 13 | NO 14 | YES 15 | ''' 16 | 17 | 18 | def is_balanced(brackets): 19 | open_brackets = ["(","{","["] 20 | close_brackets = [")","}","]"] 21 | bracket_matches = {")":"(", "}":"{", "]":"["} 22 | stack = Stack() 23 | 24 | # loop through each brackets 25 | for bracket in brackets: 26 | # if open, 27 | if bracket in open_brackets: 28 | # store in stack 29 | stack.push(bracket) 30 | # if closed, 31 | else: 32 | # check if the top of the stack is the open bracket of the same type 33 | if bracket_matches[bracket] == stack.peak(): 34 | # remove the pair 35 | stack.pop() 36 | # otherwise, 37 | else: 38 | # invalid string 39 | return False 40 | 41 | # after looping through, valid if the stack is empty 42 | # invalid otherwise 43 | return not stack.size() 44 | if __name__ == "__main__": 45 | print is_balanced("{[()]}") 46 | print is_balanced("{[(])}") 47 | print is_balanced("{{[[(())]]}}") 48 | -------------------------------------------------------------------------------- /stacks_queues/p3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implement a queue with two stacks 3 | ''' 4 | 5 | from p0 import Stack 6 | 7 | class QueueWithStacks: 8 | def __init__(self): 9 | self.stack1 = Stack() 10 | self.stack2 = Stack() 11 | 12 | def enqueue(self,el): 13 | self.stack1.push(el) 14 | 15 | def dequeue(self): 16 | if not self.stack2.size > 0: 17 | self.move_content() 18 | return self.stack2.pop() 19 | 20 | def move_content(self): 21 | while self.stack1.size > 0: 22 | self.stack2.push(self.stack1.pop()) 23 | -------------------------------------------------------------------------------- /stacks_queues/p4.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Write a program to sort a stack in ascending order (with biggest items on top). 3 | You may use at most one additional stack to hold items, 4 | but you may not copy the elements into any other data structure (suchasan array). 5 | The stack supports the following operations: push, pop, peek, and isEmpty. 6 | ''' 7 | from p0 import Stack 8 | 9 | def sort_stack(stack): 10 | result = Stack() 11 | while stack.size() > 0: 12 | # pop the top el from stack 13 | el = stack.pop() 14 | # until the top el is smaller than el 15 | num_popped_from_result = 0 16 | while result.peak() > el: 17 | # pop els from result and push them to stack 18 | stack.push(result.pop()) 19 | num_popped_from_result += 1 20 | # push el 21 | result.push(el) 22 | # push els popped back to result 23 | for i in range(num_popped_from_result): 24 | result.push(stack.pop()) 25 | return result 26 | 27 | if __name__ == "__main__": 28 | stack = Stack() 29 | stack.push(4) 30 | stack.push(5) 31 | stack.push(2) 32 | stack.push(1) 33 | stack = sort_stack(stack) 34 | print stack.stack 35 | --------------------------------------------------------------------------------