├── 1. Big O Notation ├── 1 - bigo-forloop.py ├── 10 - SpaceComplexity-2.py ├── 2 - bigo-whileloop.py ├── 3 - bigo-search.py ├── 4 - bigo-1.py ├── 5 - CountingOperations.py ├── 6 - bigo-rule4.py ├── 7 - bigo-n2.py ├── 8 - bigo-rule5.py └── 9 - SpaceComplexity-1.py ├── 2. Data Structures └── tool.txt ├── 3. Algorithms - Searching ├── 1 - LinearSearch.py ├── 2 - BinarySearch.py └── 3 - BinarySearch-Recursion.py ├── 4. Algorithms - Sorting ├── 1 - BubbleSort.py ├── 2 - SelectionSort.py ├── 3 - InsertionSort.py ├── 4 - QuickSort.py └── 5 - MergeSort.py ├── 5. Algorithms - Tree Traversal ├── 1 - BinaryTree-Implementation.py ├── 2 - TreeTraversal-BFT.py └── 3 - TreeTraversal-DFS.py ├── 6. Algorithms - Graph Traversal ├── 1 - GraphImplementation.py ├── 2 - GraphTraversal-BFS.py └── 3 - GraphTraversal-DFS.py ├── 7. Implementations and Interview Questions ├── 1 - TwoSum.py ├── 10 - ReverseString.py ├── 11 - LongestPalindromicSubstring.py ├── 2 - MinStack.py ├── 3 - MaxStack.py ├── 4 - DesignLinedList.py ├── 5 - ReverseLinkedList.py ├── 6 - ConstructBinaryTreePI.py ├── 7 - InvertBinaryTree.py ├── 8 - ConstructBinarySearchTree.py └── 9 - DetectCapital.py └── README.md /1. Big O Notation/1 - bigo-forloop.py: -------------------------------------------------------------------------------- 1 | import time 2 | time.time() 3 | 4 | timestamp1 = time.time() 5 | 6 | ### Python Program to find Sum of N Natural Numbers ### 7 | number = 100 8 | total = 0 9 | 10 | for value in range(1, number + 1): 11 | total = total + value 12 | 13 | print("The sum is", total) 14 | 15 | ### Program Completed ### 16 | 17 | timestamp2 = time.time() 18 | print((timestamp2 - timestamp1)) -------------------------------------------------------------------------------- /1. Big O Notation/10 - SpaceComplexity-2.py: -------------------------------------------------------------------------------- 1 | def all_cubes(items): 2 | result = [] 3 | 4 | for item in items: 5 | result.append(pow(item,3)) #O(n) 6 | 7 | print(result) 8 | 9 | items = [2,3,4,5,6,7] 10 | all_cubes(items) -------------------------------------------------------------------------------- /1. Big O Notation/2 - bigo-whileloop.py: -------------------------------------------------------------------------------- 1 | import time 2 | time.time() 3 | 4 | timestamp1 = time.time() 5 | 6 | # Sum of natural numbers up to num 7 | num = 100 8 | if num < 0: 9 | print("Enter a positive number") 10 | else: 11 | sum = 0 12 | # use while loop to iterate until zero 13 | while(num > 0): 14 | sum += num 15 | num -= 1 16 | print("The sum is", sum) 17 | 18 | ### Program Completed ### 19 | 20 | timestamp2 = time.time() 21 | print((timestamp2 - timestamp1)) -------------------------------------------------------------------------------- /1. Big O Notation/3 - bigo-search.py: -------------------------------------------------------------------------------- 1 | student_list1 = ['tim', 'drake', 'ashish', 'shubham'] 2 | 3 | student_list2 = ['andrew', 'harshit', 'lary', 'shubham', 'chris'] 4 | 5 | def checkStudent(student_list2): 6 | for student in student_list2: 7 | if student == 'chris': 8 | print('Available') 9 | 10 | checkStudent(student_list2) -------------------------------------------------------------------------------- /1. Big O Notation/4 - bigo-1.py: -------------------------------------------------------------------------------- 1 | student_list = ['andrew', 'akshat', 'chris', 'harshit', 'lary', 'shubham', 'tim', 'drake', 'ashish'] 2 | 3 | def displayStudent(student_list): 4 | print(student_list[0]) #O(1) 5 | print(student_list[1]) #O(1) 6 | 7 | displayStudent(student_list) #O(2) -------------------------------------------------------------------------------- /1. Big O Notation/5 - CountingOperations.py: -------------------------------------------------------------------------------- 1 | students = ['andrew', 'akshat', 'chris', 'harshit', 'lary', 'tim', 'drake', 'ashish', 'shubham'] 2 | 3 | def rondomFunction(students): 4 | first = students[0] #O(1) 5 | total = 0 #O(1) 6 | new_list = [] #O(1) 7 | 8 | for student in students: 9 | total += 1 #O(n) 10 | new_list.append(student) #O(n) 11 | 12 | print(new_list) #O(1) 13 | return total #O(1) 14 | 15 | print(rondomFunction(students)) # O(n) => O(n) -------------------------------------------------------------------------------- /1. Big O Notation/6 - bigo-rule4.py: -------------------------------------------------------------------------------- 1 | #Rule 4 - Consider different variable for different inputs 2 | 3 | num_list = [1, 2, 3, 4, 5, 6, 7] 4 | 5 | def rondomFunction(num_list, char_list): 6 | 7 | for num in num_list: 8 | print(num) #O(n) 9 | 10 | for num in num_list: 11 | print(num) #O(n) 12 | 13 | print(rondomFunction(num_list, char_list)) #O(n + n) => O(2n) => O(n) -------------------------------------------------------------------------------- /1. Big O Notation/7 - bigo-n2.py: -------------------------------------------------------------------------------- 1 | num_list = [1, 2, 3, 4, 5, 6, 7] 2 | num_list2 = [5, 6, 7, 8, 9] 3 | 4 | def rondomFunction(num_list): 5 | total = 0 6 | 7 | for num1 in num_list2: 8 | for num2 in num_list: 9 | print(num1, num2) 10 | total += 1 11 | 12 | return total 13 | 14 | print(rondomFunction(num_list)) -------------------------------------------------------------------------------- /1. Big O Notation/8 - bigo-rule5.py: -------------------------------------------------------------------------------- 1 | #Rule 5 - Remove all non-dominants 2 | 3 | num_list = [1, 2, 3, 4, 5, 6, 7] 4 | 5 | def rondomFunction(num_list): 6 | total = 0 #O(1) 7 | all_integer = True #O(1) 8 | 9 | for num in num_list: 10 | print(num) #O(n) 11 | 12 | for num1 in num_list: 13 | for num2 in num_list: 14 | print(num1, num2) #O(n^2) 15 | total += 1 #O(n^2) 16 | 17 | msg = "Rule 5 - Remove all non-dominants" #O(1) 18 | return total #O(1) 19 | 20 | print(rondomFunction(num_list)) #O(n^2) -------------------------------------------------------------------------------- /1. Big O Notation/9 - SpaceComplexity-1.py: -------------------------------------------------------------------------------- 1 | def display_cube(items): 2 | 3 | result = pow(items[0],3) #O(1) 4 | print (result) 5 | 6 | items = [2,3,4,5,6,7,10,15] 7 | display_cube(items) -------------------------------------------------------------------------------- /2. Data Structures/tool.txt: -------------------------------------------------------------------------------- 1 | 1. https://visualgo.net/en 2 | 3 | 2. https://www.cs.usfca.edu/~galles/visualization/ 4 | RedBlack Tree: https://www.cs.usfca.edu/~galles/visualization/RedBlack.html 5 | Trie: https://www.cs.usfca.edu/~galles/visualization/Trie.html -------------------------------------------------------------------------------- /3. Algorithms - Searching/1 - LinearSearch.py: -------------------------------------------------------------------------------- 1 | def linearSearch(my_array, target): 2 | 3 | for i in range(len(my_array)): 4 | if my_array[i] == target: 5 | return i 6 | 7 | return -1 8 | 9 | linearSearch([5, 3, 1, 9, 2], 9) -------------------------------------------------------------------------------- /3. Algorithms - Searching/2 - BinarySearch.py: -------------------------------------------------------------------------------- 1 | def binarySearch(my_array, target): 2 | left = 0 3 | right = len(my_array) - 1 4 | 5 | while left <= right: 6 | middle = (left + right) // 2 7 | middle_element = my_array[middle] 8 | 9 | if target == middle_element: 10 | return middle 11 | elif target < middle_element: 12 | right = middle - 1 13 | else: 14 | left = middle + 1 15 | 16 | return -1 17 | 18 | ### Test 1 ### 19 | print(binarySearch([1, 5, 10, 12, 25, 30, 32], 29)) 20 | 21 | ### Test 2 ### 22 | print(binarySearch([5, 10, 15, 20, 25], 15)) -------------------------------------------------------------------------------- /3. Algorithms - Searching/3 - BinarySearch-Recursion.py: -------------------------------------------------------------------------------- 1 | 2 | def binarySearch(my_array, target): 3 | left = 0 4 | right = len(my_array) - 1 5 | result = helper(my_array, target, left, right) 6 | return result 7 | 8 | def helper(my_array, target, left, right): 9 | if left > right: 10 | return -1 11 | 12 | middle = (left + right) // 2 13 | middle_element = my_array[middle] 14 | 15 | if target == middle_element: 16 | return middle 17 | elif target < middle_element: 18 | right = middle - 1 19 | result = helper(my_array, target, left, right) 20 | return result 21 | else: 22 | left = middle + 1 23 | result = helper(my_array, target, left, right) 24 | return result -------------------------------------------------------------------------------- /4. Algorithms - Sorting/1 - BubbleSort.py: -------------------------------------------------------------------------------- 1 | def bubbleSort(arr): 2 | 3 | for iter in range(len(arr)): 4 | for index in range(0, len(arr) - 1 - iter): 5 | if arr[index] > arr[index + 1]: 6 | arr[index], arr[index + 1] = arr[index + 1], arr[index] 7 | 8 | arr = [29, 10, 14, 37, 14] 9 | bubbleSort(arr) 10 | 11 | print(arr) -------------------------------------------------------------------------------- /4. Algorithms - Sorting/2 - SelectionSort.py: -------------------------------------------------------------------------------- 1 | def selectionSort(arr): 2 | 3 | for i in range(len(arr)): 4 | min_x = i 5 | 6 | for item in range(i+1, len(arr)): 7 | if arr[item] < arr[min_x]: 8 | min_x = item 9 | 10 | arr[i], arr[min_x] = arr[min_x], arr[i] 11 | 12 | arr = [20, 12, 10, 15, 2] 13 | selectionSort(arr) 14 | 15 | print(arr) -------------------------------------------------------------------------------- /4. Algorithms - Sorting/3 - InsertionSort.py: -------------------------------------------------------------------------------- 1 | def insertionSort(arr): 2 | 3 | for i in range(1, len(arr)): 4 | key = arr[i] 5 | last = i - 1 6 | 7 | while last >= 0 and key < arr[last]: 8 | arr[last +1] = arr[last] 9 | last = last - 1 10 | 11 | arr[last + 1] = key 12 | 13 | arr = [1, 2, 3, 4, 5] 14 | insertionSort(arr) 15 | 16 | print(arr) -------------------------------------------------------------------------------- /4. Algorithms - Sorting/4 - QuickSort.py: -------------------------------------------------------------------------------- 1 | def quickSort(my_array): 2 | qshelper(my_array, 0, len(my_array) - 1) 3 | return my_array 4 | 5 | def qshelper(my_array, start, end): 6 | if start >= end: 7 | return 8 | 9 | pivot = start 10 | left = start + 1 11 | right = end 12 | 13 | while right >= left: 14 | 15 | if my_array[left] > my_array[pivot] and my_array[right] < my_array[pivot]: 16 | my_array[left], my_array[right] = my_array[right], my_array[left] 17 | 18 | if my_array[left] <= my_array[pivot]: 19 | left += 1 20 | 21 | if my_array[right] >= my_array[pivot]: 22 | right -= 1 23 | 24 | my_array[pivot], my_array[right] = my_array[right], my_array[pivot] 25 | 26 | qshelper(my_array, start, right - 1) 27 | qshelper(my_array, right + 1, end) -------------------------------------------------------------------------------- /4. Algorithms - Sorting/5 - MergeSort.py: -------------------------------------------------------------------------------- 1 | def mergeSort(my_array): 2 | if len(my_array) == 1: 3 | return my_array 4 | 5 | middle = len(my_array) // 2 6 | left = my_array[:middle] 7 | right = my_array[middle:] 8 | 9 | left_result = mergeSort(left) 10 | right_result = mergeSort(right) 11 | 12 | return merge(left_result, right_result) 13 | 14 | def merge(left_result, right_result): 15 | result = [None] * (len(left_result) + len(right_result)) 16 | i = j = k = 0 17 | 18 | while i < len(left_result) and j < len(right_result): 19 | if left_result[i] <= right_result[j]: 20 | result[k] = left_result[i] 21 | i += 1 22 | else: 23 | result[k] = right_result[j] 24 | j += 1 25 | k += 1 26 | 27 | while i < len(left_result): 28 | result[k] = left_result[i] 29 | i += 1 30 | k += 1 31 | 32 | while j < len(right_result): 33 | result[k] = right_result[j] 34 | j += 1 35 | k += 1 36 | 37 | return result 38 | 39 | numbers = [4, 5, 6, 1, 3, 7, 2] 40 | print(mergeSort(numbers)) -------------------------------------------------------------------------------- /5. Algorithms - Tree Traversal/1 - BinaryTree-Implementation.py: -------------------------------------------------------------------------------- 1 | class Node(): 2 | def __init__(self, value): 3 | self.value = value 4 | self.left = None 5 | self.right = None 6 | 7 | 8 | class BinaryTree(): 9 | def __init__(self, value): 10 | self.root = Node(value) 11 | 12 | 13 | tree = BinaryTree(3) 14 | 15 | tree.root.left = Node(4) 16 | tree.root.left.left = Node(6) 17 | tree.root.left.right = Node(7) 18 | 19 | tree.root.right = Node(5) 20 | tree.root.right.left = Node(8) 21 | tree.root.right.right = Node(9) -------------------------------------------------------------------------------- /5. Algorithms - Tree Traversal/2 - TreeTraversal-BFT.py: -------------------------------------------------------------------------------- 1 | class Queue(): 2 | def __init__(self): 3 | self.items = [] 4 | 5 | def enqueue(self, item): 6 | self.items.append(item) 7 | 8 | def dequeue(self): 9 | if len(self.items): 10 | return self.items.pop(0) 11 | 12 | def peek(self): 13 | if len(self.items): 14 | return self.items[0].value 15 | 16 | 17 | class Node(): 18 | def __init__(self, value): 19 | self.value = value 20 | self.left = None 21 | self.right = None 22 | 23 | class BinaryTree(): 24 | def __init__(self, value): 25 | self.root = Node(value) 26 | 27 | def levelorder(self, start): 28 | if start is None: 29 | return 30 | 31 | queue = Queue() 32 | queue.enqueue(start) 33 | traversal = [] 34 | 35 | while len(queue.items) > 0: 36 | traversal.append(queue.peek()) 37 | node = queue.dequeue() 38 | 39 | if node.left: 40 | queue.enqueue(node.left) 41 | if node.right: 42 | queue.enqueue(node.right) 43 | 44 | return traversal 45 | 46 | tree = BinaryTree(3) 47 | 48 | tree.root.left = Node(4) 49 | tree.root.left.left = Node(6) 50 | tree.root.left.right = Node(7) 51 | 52 | tree.root.left.left.right = Node(20) 53 | 54 | tree.root.right = Node(5) 55 | tree.root.right.left = Node(8) 56 | tree.root.right.right = Node(9) 57 | 58 | tree.root.right.left.left = Node(10) 59 | 60 | print(tree.levelorder(tree.root)) -------------------------------------------------------------------------------- /5. Algorithms - Tree Traversal/3 - TreeTraversal-DFS.py: -------------------------------------------------------------------------------- 1 | class Node(): 2 | def __init__(self, value): 3 | self.value = value 4 | self.left = None 5 | self.right = None 6 | 7 | class BinaryTree(): 8 | def __init__(self, value): 9 | self.root = Node(value) 10 | 11 | def preorder(self, start, traversal): 12 | # Root -> Left -> Right 13 | if start is None: 14 | return 15 | 16 | traversal.append(start.value) 17 | self.preorder(start.left, traversal) 18 | self.preorder(start.right, traversal) 19 | 20 | return traversal 21 | 22 | def inorder(self, start, traversal): 23 | # Left -> Root -> Right 24 | if start is None: 25 | return 26 | 27 | self.inorder(start.left, traversal) 28 | traversal.append(start.value) 29 | self.inorder(start.right, traversal) 30 | 31 | return traversal 32 | 33 | def postorder(self, start, traversal): 34 | # Left -> Right -> Root 35 | if start is None: 36 | return 37 | 38 | self.postorder(start.left, traversal) 39 | self.postorder(start.right, traversal) 40 | traversal.append(start.value) 41 | 42 | return traversal 43 | 44 | tree = BinaryTree(3) 45 | 46 | tree.root.left = Node(4) 47 | tree.root.left.left = Node(6) 48 | tree.root.left.right = Node(7) 49 | 50 | tree.root.right = Node(5) 51 | tree.root.right.left = Node(8) 52 | tree.root.right.right = Node(9) 53 | 54 | print(tree.preorder(tree.root, [])) 55 | print(tree.inorder(tree.root, [])) 56 | print(tree.postorder(tree.root, [])) -------------------------------------------------------------------------------- /6. Algorithms - Graph Traversal/1 - GraphImplementation.py: -------------------------------------------------------------------------------- 1 | class Node(): 2 | 3 | def __init__(self, value): 4 | self.value = value 5 | self.adjacentlist = [] 6 | self.visited = False 7 | 8 | class Graph(): 9 | pass 10 | 11 | node1 = Node("A") 12 | node2 = Node("B") 13 | node3 = Node("C") 14 | node4 = Node("D") 15 | node5 = Node("E") 16 | node6 = Node("F") 17 | node7 = Node("G") 18 | 19 | node1.adjacentlist.append(node2) 20 | node1.adjacentlist.append(node3) 21 | node1.adjacentlist.append(node4) 22 | node2.adjacentlist.append(node5) 23 | node2.adjacentlist.append(node6) 24 | node4.adjacentlist.append(node7) -------------------------------------------------------------------------------- /6. Algorithms - Graph Traversal/2 - GraphTraversal-BFS.py: -------------------------------------------------------------------------------- 1 | class Node(): 2 | 3 | def __init__(self, value): 4 | self.value = value 5 | self.adjacentlist = [] 6 | self.visited = False 7 | 8 | class Graph(): 9 | 10 | def BFS(self, node): 11 | 12 | queue = [] 13 | queue.append(node) 14 | node.visited = True 15 | 16 | traversal = [] 17 | 18 | while queue: 19 | actualNode = queue.pop(0) 20 | traversal.append(actualNode.value) 21 | 22 | for element in actualNode.adjacentlist: 23 | if element.visited is False: 24 | queue.append(element) 25 | element.visited = True 26 | 27 | return traversal 28 | 29 | node1 = Node("A") 30 | node2 = Node("B") 31 | node3 = Node("C") 32 | node4 = Node("D") 33 | node5 = Node("E") 34 | node6 = Node("F") 35 | node7 = Node("G") 36 | 37 | node1.adjacentlist.append(node2) 38 | node1.adjacentlist.append(node3) 39 | node1.adjacentlist.append(node4) 40 | node2.adjacentlist.append(node5) 41 | node2.adjacentlist.append(node6) 42 | node4.adjacentlist.append(node7) 43 | 44 | graph = Graph() 45 | print(graph.BFS(node1)) -------------------------------------------------------------------------------- /6. Algorithms - Graph Traversal/3 - GraphTraversal-DFS.py: -------------------------------------------------------------------------------- 1 | class Node(): 2 | 3 | def __init__(self, value): 4 | self.value = value 5 | self.adjacentlist = [] 6 | self.visited = False 7 | 8 | class Graph(): 9 | 10 | def DFS(self, node, traversal): 11 | node.visited = True 12 | traversal.append(node.value) 13 | 14 | for element in node.adjacentlist: 15 | if element.visited is False: 16 | self.DFS(element, traversal) 17 | 18 | return traversal 19 | 20 | node1 = Node("A") 21 | node2 = Node("B") 22 | node3 = Node("C") 23 | node4 = Node("D") 24 | node5 = Node("E") 25 | node6 = Node("F") 26 | node7 = Node("G") 27 | node8 = Node("H") 28 | 29 | node1.adjacentlist.append(node2) 30 | node1.adjacentlist.append(node3) 31 | node1.adjacentlist.append(node4) 32 | node2.adjacentlist.append(node5) 33 | node2.adjacentlist.append(node6) 34 | node4.adjacentlist.append(node7) 35 | node6.adjacentlist.append(node8) 36 | 37 | graph = Graph() 38 | print(graph.DFS(node1, [])) -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/1 - TwoSum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def twoSum(self, nums, target): 3 | store = {} 4 | 5 | for i in range(len(nums)): 6 | if nums[i] in store: 7 | return [store[nums[i]], i] 8 | else: 9 | store[target-nums[i]] = i 10 | 11 | 12 | ## Example Execution ## 13 | obj = Solution() 14 | result = obj.twoSum([2,7,11,15], 9) 15 | print(result) -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/10 - ReverseString.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseString(self, s): 3 | """ 4 | Do not return anything, modify s in-place instead. 5 | """ 6 | 7 | left = 0 8 | right = len(s) - 1 9 | 10 | while left < right: 11 | s[left], s[right] = s[right], s[left] 12 | left += 1 13 | right -= 1 -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/11 - LongestPalindromicSubstring.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | 3 | def longestPalindrome(self, s): 4 | result = "" 5 | for i in range(len(s)): 6 | word1 = self.checkPalindrome(s, i, i) 7 | word2 = self.checkPalindrome(s, i, i+1) 8 | 9 | if len(word1) >= len(word2): 10 | longest = word1 11 | else: 12 | longest = word2 13 | 14 | if len(longest) >= len(result): 15 | result = longest 16 | else: 17 | result = result 18 | 19 | return result 20 | 21 | 22 | def checkPalindrome(self, s, left, right): 23 | 24 | while left >= 0 and right < len(s) and s[left]==s[right]: 25 | left -= 1 26 | right += 1 27 | 28 | return s[left+1:right] -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/2 - MinStack.py: -------------------------------------------------------------------------------- 1 | class MinStack: 2 | 3 | def __init__(self): 4 | self.stack = [] 5 | self.min = [] 6 | 7 | def push(self, x): 8 | self.stack.append(x) 9 | 10 | if self.min: 11 | if x <= self.min[-1]: 12 | self.min.append(x) 13 | else: 14 | self.min.append(x) 15 | 16 | def pop(self): 17 | if self.stack[-1] == self.min[-1]: 18 | self.min.pop() 19 | self.stack.pop() 20 | 21 | def top(self): 22 | return self.stack[-1] 23 | 24 | def getMin(self): 25 | return self.min[-1] 26 | 27 | 28 | ## Example Execution ## 29 | obj = MinStack() 30 | obj.push(10) 31 | obj.push(5) 32 | obj.push(15) 33 | obj.pop() 34 | obj.push(20) 35 | 36 | result_top = obj.top() 37 | print("Top Value:", result_top) 38 | 39 | result_min = obj.getMin() 40 | print("Minimum Value in Stack:", result_min) -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/3 - MaxStack.py: -------------------------------------------------------------------------------- 1 | class MaxStack: 2 | 3 | def __init__(self): 4 | self.stack = [] 5 | self.max = [] 6 | 7 | def push(self, x): 8 | self.stack.append(x) 9 | 10 | if self.max: 11 | if x >= self.max[-1]: 12 | self.max.append(x) 13 | else: 14 | self.max.append(x) 15 | 16 | def pop(self): 17 | if self.stack[-1] == self.max[-1]: 18 | self.max.pop() 19 | self.stack.pop() 20 | 21 | def top(self): 22 | return self.stack[-1] 23 | 24 | def getMax(self): 25 | return self.max[-1] 26 | 27 | 28 | ## Example Execution ## 29 | obj = MaxStack() 30 | obj.push(10) 31 | obj.push(5) 32 | obj.pop() 33 | obj.push(20) 34 | obj.push(15) 35 | 36 | result_top = obj.top() 37 | print("Top Value:", result_top) 38 | 39 | result_max = obj.getMax() 40 | print("Maximum Value in Stack:", result_max) -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/4 - DesignLinedList.py: -------------------------------------------------------------------------------- 1 | class ListNode: 2 | def __init__(self, val): 3 | self.val = val 4 | self.prev = None 5 | self.next = None 6 | 7 | class MyLinkedList: 8 | 9 | def __init__(self): 10 | self.head = None 11 | self.tail = None 12 | self.size = 0 13 | 14 | 15 | def get(self, index): 16 | if index < 0 or index >= self.size: 17 | return -1 18 | 19 | cur = self.head 20 | 21 | while index != 0: 22 | cur = cur.next 23 | index = index - 1 24 | 25 | return cur.val 26 | 27 | 28 | def addAtHead(self, val): 29 | new_node = ListNode(val) 30 | 31 | if self.head is None: 32 | self.head = new_node 33 | self.tail = new_node 34 | else: 35 | new_node.next = self.head 36 | self.head.prev = new_node 37 | self.head = new_node 38 | 39 | self.size += 1 40 | 41 | def addAtTail(self, val): 42 | new_node = ListNode(val) 43 | 44 | if self.head is None: 45 | self.head = new_node 46 | self.tail = new_node 47 | else: 48 | new_node.prev = self.tail 49 | self.tail.next = new_node 50 | self.tail = new_node 51 | 52 | self.size += 1 53 | 54 | 55 | def addAtIndex(self, index, val): 56 | if index < 0 or index > self.size: 57 | return 58 | elif index == 0: 59 | self.addAtHead(val) 60 | elif index == self.size: 61 | self.addAtTail(val) 62 | else: 63 | cur = self.head 64 | while index-1 != 0: 65 | cur = cur.next 66 | index -= 1 67 | 68 | new_node = ListNode(val) 69 | 70 | new_node.next = cur.next 71 | cur.next.prev = new_node 72 | cur.next = new_node 73 | new_node.prev = cur 74 | 75 | self.size += 1 76 | 77 | 78 | def deleteAtIndex(self, index): 79 | if index < 0 or index >= self.size: 80 | return 81 | elif index == 0: 82 | cur = self.head.next 83 | if cur: 84 | cur.prev = None 85 | 86 | self.head = self.head.next 87 | self.size -= 1 88 | 89 | if self.size == 0: 90 | self.tail = None 91 | elif index == self.size-1: 92 | cur = self.tail.prev 93 | if cur: 94 | cur.next = None 95 | self.tail = self.tail.prev 96 | 97 | self.size -= 1 98 | 99 | if self.size == 0: 100 | self.head = None 101 | else: 102 | cur = self.head 103 | while index-1 != 0: 104 | cur = cur.next 105 | index -= 1 106 | 107 | cur.next = cur.next.next 108 | cur.next.prev = cur 109 | 110 | self.size -= 1 111 | 112 | 113 | ## Example Execution ## 114 | obj = MyLinkedList() 115 | obj.addAtHead(10) 116 | obj.addAtTail(15) 117 | obj.addAtTail(20) 118 | obj.deleteAtIndex(0) 119 | obj.addAtHead(40) 120 | 121 | print(obj.get(1)) -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/5 - ReverseLinkedList.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | class Solution: 8 | def reverseList(self, head): 9 | pre = None 10 | cur = head 11 | suc = None 12 | 13 | while cur: 14 | suc = cur.next 15 | cur.next = pre 16 | pre = cur 17 | cur = suc 18 | 19 | return pre -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/6 - ConstructBinaryTreePI.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | class Solution: 9 | def buildTree(self, preorder, inorder): 10 | memory = {} 11 | for i, e in enumerate(inorder): 12 | memory[e] = i 13 | 14 | root = self.helper(preorder[::-1], inorder, 0, len(inorder), memory) 15 | return root 16 | 17 | 18 | def helper(self, preorder, inorder, leftPointer, rightPointer, memory): 19 | if leftPointer >= rightPointer: 20 | return None 21 | 22 | num = preorder.pop() 23 | root = TreeNode(num) 24 | idx = memory.get(num) 25 | 26 | root.left = self.helper(preorder, inorder, leftPointer, idx, memory) 27 | root.right = self.helper(preorder, inorder, idx+1, rightPointer, memory) 28 | 29 | return root 30 | -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/7 - InvertBinaryTree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | class Solution: 9 | def invertTree(self, root): 10 | 11 | if root is None: 12 | return None 13 | 14 | root.left, root.right = root.right, root.left 15 | 16 | self.invertTree(root.left) 17 | self.invertTree(root.right) 18 | 19 | return root -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/8 - ConstructBinarySearchTree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | class Solution: 9 | def bstFromPreorder(self, preorder): 10 | 11 | root = TreeNode(preorder[0]) 12 | stack = [root] 13 | 14 | for i in range(1, len(preorder)): 15 | if preorder[i] < stack[-1].val: 16 | node = TreeNode(preorder[i]) 17 | stack[-1].left = node 18 | stack.append(node) 19 | else: 20 | while stack and stack[-1].val < preorder[i]: 21 | pop = stack.pop() 22 | node = TreeNode(preorder[i]) 23 | pop.right = node 24 | stack.append(node) 25 | 26 | return root -------------------------------------------------------------------------------- /7. Implementations and Interview Questions/9 - DetectCapital.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def detectCapitalUse(self, word): 3 | count = 0 4 | length = len(word) 5 | 6 | for i in range(length): 7 | if word[i] >= chr(65) and word[i] < chr(91): 8 | count += 1 9 | 10 | if count == length: 11 | return True 12 | elif count == 0: 13 | return True 14 | elif count == 1 and word[0] >= chr(65) and word[0] < chr(91): 15 | return True 16 | else: 17 | return False -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome To DSA Bootcamp 3 | 4 | - The repository consists of all the major files we use throughout the course. 5 | - Initial number with filenames doesn't donotes anything, they are used just to maintain the sequence. 6 | 7 | 8 | ## Course Curriculum 9 | 10 | Throughout the course, we will explore the most important Data Structures and Algorithms topics step-by-step: 11 | 12 | **1. Essential Concepts** 13 | - Big O Notation 14 | - Memory 15 | - Logarithms 16 | - Recursion 17 | 18 | **2. Data structures:** 19 | - Arrays 20 | - Linked Lists (Singly Linked List, Doubly Linked List, Circular Linked List) 21 | - Stacks- Queues- Hash Tables 22 | - Trees (Binary Tree, Binary Search Tree, AVL Trees, Red-Black Trees) 23 | - Heaps (Binary Heaps) 24 | - Tries 25 | - Graphs 26 | 27 | **3. Algorithms:** 28 | - Elementary Sorting Algorithms (Bubble Sort, Insertion Sort, Selection Sort) 29 | - Advance Searching Algorithms (Quick Sort, Merge Sort) 30 | - Tree Traversal (Breadth First Search: Level Order Traversal and Depth First Search: PreOrder, InOrder, PostOrder) 31 | - Graph Traversal (Breadth-First Search, Depth First Search) 32 | 33 | **4. Interview Questions** 34 | - Two Sum 35 | - MinMax Stack 36 | - Design Linked List 37 | - Reverse Linked List 38 | - Construct Binary Tree 39 | - Invert Binary Tree 40 | - Construct Binary Search Tree 41 | - Detect Capital 42 | - Reverse String 43 | - Longest Palindromic Substring 44 | --------------------------------------------------------------------------------