diff --git a/Exercise_1.py b/Exercise_1.py index 3e6adcf4..74dd1712 100644 --- a/Exercise_1.py +++ b/Exercise_1.py @@ -3,11 +3,26 @@ # It returns location of x in given array arr # if present, else returns -1 +# Time Complexity: O(log n) +# Space Complexity: O(1) def binarySearch(arr, l, r, x): - #write your code here - + while l <= r: + # Checking the mid of an array + mid = l + (r - 1) // 2 + # Checking if the value to search is in the mid + if arr[mid] == x: + return mid + # if search value is greater - ignore the first half of the array plus the mid + elif arr[mid] < x: + l = mid + 1 + # Else search value is lesser - ignore the second half of the array plus the mid + else: + r = mid - 1 + # Search Value not found + return -1 + # Test array arr = [ 2, 3, 4, 10, 40 ] @@ -17,6 +32,6 @@ def binarySearch(arr, l, r, x): result = binarySearch(arr, 0, len(arr)-1, x) if result != -1: - print "Element is present at index % d" % result + print ("Element is present at index % d" % result) else: - print "Element is not present in array" + print ("Element is not present in array") diff --git a/Exercise_2.py b/Exercise_2.py index 35abf0dd..6f14df15 100644 --- a/Exercise_2.py +++ b/Exercise_2.py @@ -1,23 +1,46 @@ # Python program for implementation of Quicksort Sort - # give you explanation for the approach + +# Given an array arr[], partition the array by assuming last element as pivot element. +# The partition of an array must satisfy the following two conditions: +# Elements smaller than the pivot element appear before pivot in the array. +# Elements larger than or equal to the pivot element appear after pivot it in the array. + +# Time and Space complexity: +# Time Complexity: O(n log n) +# Space Complexity: O(log n) def partition(arr,low,high): - - #write your code here - + # Taking the last element as the pivot + pivot = arr[high] + i = low - 1 # Initial boundary before the first element ie 'low' + + for j in range(low, high): + # Checking if the current element is smaller or equal to the pivot + if arr[j] <= pivot: + # Check the next value + i += 1 + arr[i], arr[j] = arr[j], arr[i] # swapping the value using python unpacking + + arr[i + 1], arr[high] = arr[high], arr[i + 1] # swapping the pivot value to the right position + return i + 1 + # Function to do Quick sort def quickSort(arr,low,high): - #write your code here - + if low < high: + # partition the array + part = partition(arr, low, high) + + # recursive call + quickSort(arr, low, part - 1) + quickSort(arr, part + 1, high) + # Driver code to test above arr = [10, 7, 8, 9, 1, 5] n = len(arr) quickSort(arr,0,n-1) print ("Sorted array is:") for i in range(n): - print ("%d" %arr[i]), - - + print ("%d" %arr[i]), diff --git a/Exercise_3.py b/Exercise_3.py index a26a69b8..c4bd8f4a 100644 --- a/Exercise_3.py +++ b/Exercise_3.py @@ -1,20 +1,41 @@ +# Time and Space complexity: +# Time Complexity: O(n) +# Space Complexity: O(1) # Node class class Node: - # Function to initialise the node object - def __init__(self, data): + def __init__(self, data): + self.data = data + self.next = None class LinkedList: - - def __init__(self): + def __init__(self): + self.head = None - def push(self, new_data): + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node + - # Function to get the middle of # the linked list def printMiddle(self): + # Most efficient way to get the middle is to use two pointers + slow = self.head + fast = self.head + + # Move fast pointer by 2 and slow pointer by 1 + # Doing so when the fast pointer is pointing at the last element + # Slow pointer will point to the exact middle + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + if slow: + print("The middle element is: ", slow.data) + else: + print("The list is empty") # Driver code list1 = LinkedList() diff --git a/Exercise_4.py b/Exercise_4.py index 9bc25d3d..d81da4c7 100644 --- a/Exercise_4.py +++ b/Exercise_4.py @@ -1,13 +1,46 @@ +# Time and Space complexity: +# Time Complexity: O(n log n) +# Space Complexity: O(n) # Python program for implementation of MergeSort def mergeSort(arr): - #write your code here + if len(arr) > 1: + # find the mid + mid = len(arr) // 2 + l = arr[:mid] # before mid + r = arr[mid:] # after mid + + mergeSort(l) + mergeSort(r) + + i = j = k = 0 + + while i < len(l) and j < len(r): + if l[i] < r[j]: + arr[k] = l[i] + i += 1 + else: + arr[k] = r[j] + j += 1 + k += 1 + + while i < len(l): + arr[k] = l[i] + i += 1 + k += 1 + + while j < len(r): + arr[k] = r[j] + j += 1 + k += 1 # Code to print the list def printList(arr): - #write your code here - + for i in range(len(arr)): + print(arr[i], end=" ") + print() + # driver code to test the above code if __name__ == '__main__': arr = [12, 11, 13, 5, 6, 7] diff --git a/Exercise_5.py b/Exercise_5.py index 1da24ffb..1294cf3d 100644 --- a/Exercise_5.py +++ b/Exercise_5.py @@ -1,10 +1,63 @@ -# Python program for implementation of Quicksort - -# This function is same in both iterative and recursive +# Python program for implementation of Quicksort (Iterative) +# Time and Space complexity: +# Time Complexity: O(n log n) +# Space Complexity: O(n) +# This function is same in both iterative and recursive versions def partition(arr, l, h): - #write your code here + pivot = arr[h] + i = l - 1 + + for j in range(l, h): + if arr[j] < pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] + + arr[i + 1], arr[h] = arr[h], arr[i + 1] + return i + 1 def quickSortIterative(arr, l, h): - #write your code here + size = h - l + 1 + stack = [0] * size + + # initializeing top of stack + top = -1 + + # Pushing initial values of both l and h onto stack + top += 1 + stack[top] = l + top += 1 + stack[top] = h + + # Continue to pop while stack is not empty + while top >= 0: + # Pop h and l + h = stack[top] + top -= 1 + l = stack[top] + top -= 1 + p = partition(arr, l, h) + + # If there are elements on left side of pivot, push left side to stack + if p - 1 > l: + top += 1 + stack[top] = l + top += 1 + stack[top] = p - 1 + + # If there are elements on right side of pivot, push right side to stack + if p + 1 < h: + top += 1 + stack[top] = p + 1 + top += 1 + stack[top] = h + +# Driver code +if __name__ == "__main__": + arr = [4, 2, 6, 9, 3] + n = len(arr) + quickSortIterative(arr, 0, n - 1) + print("Sorted array is:") + for i in range(n): + print(arr[i], end=" ")