From 979ecc64cf577dba89f9c4595d632ba51b7ca96b Mon Sep 17 00:00:00 2001 From: Tanya Sreenagesh Date: Sun, 28 Sep 2025 22:30:54 -0700 Subject: [PATCH] PreCourse-2 Submission --- Exercise_1.py | 32 +++++++++++++++++++++++------- Exercise_2.py | 34 +++++++++++++++++++++++-------- Exercise_3.py | 33 ++++++++++++++++++++++++++++++- Exercise_4.py | 52 +++++++++++++++++++++++++++++++++++++++++++----- Exercise_5.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 183 insertions(+), 23 deletions(-) diff --git a/Exercise_1.py b/Exercise_1.py index 3e6adcf4..c92baad5 100644 --- a/Exercise_1.py +++ b/Exercise_1.py @@ -1,22 +1,40 @@ +# Time Complexity : O(n) +# Space Complexity : O(1) +# Did this code successfully run on Leetcode : yes +# Any problem you faced while coding this : No, but remember to increment/decrement mid index + # Python code to implement iterative Binary # Search. # It returns location of x in given array arr # if present, else returns -1 -def binarySearch(arr, l, r, x): - - #write your code here +def recursiveBinarySearch(arr, l, r, x): + midIndex = int((l+r)/2) + if arr[midIndex] == x: + return midIndex + if arr[midIndex] > x: + return binarySearch(arr, l, midIndex-1, x) + else: + return binarySearch(arr, midIndex+1, r, x) - +def binarySearch(arr, l, r, x): + while l <= r: + midIndex = int((l+r)/2) + if arr[midIndex] == x: + return midIndex + if arr[midIndex] > x: + r = midIndex-1 + else: + l = midIndex+1 # Test array arr = [ 2, 3, 4, 10, 40 ] -x = 10 +x = 4 # Function call 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..e5a69914 100644 --- a/Exercise_2.py +++ b/Exercise_2.py @@ -1,16 +1,34 @@ +# Time Complexity : O(n log n) average, O(n²) worst case +# Space Complexity : O(log n) due to recursion stack +# Did this code successfully run on Leetcode : yes +# Any problem you faced while coding this : No, but remember to handle base case properly + # Python program for implementation of Quicksort Sort - -# give you explanation for the approach def partition(arr,low,high): - - - #write your code here - + # Choose rightmost element as pivot + pivot = arr[high] + + # Index of smaller element (right position of pivot) + i = low - 1 + + # Iterate through all elements + for j in range(low, high): + # If current element is smaller than or equal to pivot, swap them + if arr[j] <= pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] + + # Place pivot in correct position + arr[i + 1], arr[high] = arr[high], arr[i + 1] + return i + 1 # Function to do Quick sort def quickSort(arr,low,high): - - #write your code here + if low < high: + pivotIndex = partition(arr, low, high) + + quickSort(arr, low, pivotIndex - 1) + quickSort(arr, pivotIndex + 1, high) # Driver code to test above arr = [10, 7, 8, 9, 1, 5] diff --git a/Exercise_3.py b/Exercise_3.py index a26a69b8..91e127cb 100644 --- a/Exercise_3.py +++ b/Exercise_3.py @@ -1,20 +1,50 @@ +# Time Complexity : push O(n), printMiddle O(n) +# Space Complexity : push O(1), printMiddle O(1) - only really storing head variable +# Did this code successfully run on Leetcode : yes +# Any problem you faced while coding this : No, but remember to increment/decrement mid index + # Node class class Node: # Function to initialise the node object def __init__(self, data): + self.data = data + self.next = None class LinkedList: def __init__(self): - + self.head = None + self.count = 0 def push(self, new_data): + newNode = Node(new_data) + self.count += 1 + if self.head is None: + self.head = newNode + return + + curr = self.head + while curr.next is not None: + curr = curr.next + curr.next = newNode # Function to get the middle of # the linked list def printMiddle(self): + if self.head is None: + print("Empty list") + return + + midIndex = self.count//2 + + i = 0 + current = self.head + while i < midIndex: + current = current.next + i += 1 + print(current.data) # Driver code list1 = LinkedList() @@ -23,4 +53,5 @@ def printMiddle(self): list1.push(2) list1.push(3) list1.push(1) +list1.push(1) list1.printMiddle() diff --git a/Exercise_4.py b/Exercise_4.py index 9bc25d3d..498daaba 100644 --- a/Exercise_4.py +++ b/Exercise_4.py @@ -1,12 +1,54 @@ +# Time Complexity : O(n log n) in all cases +# Space Complexity : O(n) due to temporary arrays +# Did this code successfully run on Leetcode : yes +# Any problem you faced while coding this : No, but remember to handle merge step carefully + # Python program for implementation of MergeSort def mergeSort(arr): - - #write your code here - + if len(arr) > 1: + # Find the middle of the array + mid = len(arr) // 2 + + # Divide the array into two halves + left_half = arr[:mid] + right_half = arr[mid:] + + # Recursively sort both halves + mergeSort(left_half) + mergeSort(right_half) + + # Merge the sorted halves + # i = left index + # j = right index + i = j = curr = 0 + + # Copy data from temp arrays back to main array + while i < len(left_half) and j < len(right_half): + if left_half[i] <= right_half[j]: + arr[curr] = left_half[i] + i += 1 + else: + arr[curr] = right_half[j] + j += 1 + curr += 1 + + # Copy remaining elements of left_half + while i < len(left_half): + arr[curr] = left_half[i] + i += 1 + curr += 1 + + # Copy remaining elements of right_half + while j < len(right_half): + arr[curr] = right_half[j] + j += 1 + curr += 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__': diff --git a/Exercise_5.py b/Exercise_5.py index 1da24ffb..6f1f571d 100644 --- a/Exercise_5.py +++ b/Exercise_5.py @@ -1,10 +1,61 @@ +# Time Complexity : O(n log n) average, O(n²) worst case +# Space Complexity : O(log n) due to explicit stack +# Did this code successfully run on Leetcode : yes +# Any problem you faced while coding this : No, but remember to use explicit stack instead of recursion + # Python program for implementation of Quicksort # This function is same in both iterative and recursive def partition(arr, l, h): - #write your code here + # Choose rightmost element as pivot + pivot = arr[h] + + # Index of smaller element (right position of pivot) + i = l - 1 + + # Iterate through all elements + for j in range(l, h): + # If current element is smaller than or equal to pivot, swap them + if arr[j] <= pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] + + # Place pivot in correct position + arr[i + 1], arr[h] = arr[h], arr[i + 1] + return i + 1 def quickSortIterative(arr, l, h): - #write your code here + # Push initial values of l and h to stack + stack = [] + stack.append(l) + stack.append(h) + + # Keep popping from stack while it's not empty + while stack: + # Pop h and l + h = stack.pop() + l = stack.pop() + + pivot = partition(arr, l, h) + + # If there are elements on left side of pivot, push left side to stack + if pivot - 1 > l: + stack.append(l) + stack.append(pivot - 1) + + # If there are elements on right side of pivot, push right side to stack + if pivot + 1 < h: + stack.append(pivot + 1) + stack.append(h) + +# Driver code to test the above code +if __name__ == '__main__': + arr = [10, 7, 8, 9, 1, 5] + n = len(arr) + quickSortIterative(arr, 0, n-1) + print("Sorted array is:") + for i in range(n): + print(arr[i], end=" ") + print()