diff --git a/Exercise_1.py b/Exercise_1.py index 3e6adcf4..5b86a90a 100644 --- a/Exercise_1.py +++ b/Exercise_1.py @@ -3,9 +3,23 @@ # It returns location of x in given array arr # if present, else returns -1 +# Time Complexity : O(log n) +# Space Complexity : O(1) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No def binarySearch(arr, l, r, x): + l, r = 0, len(arr)-1 + while l<=r: + mid = (l+r)//2 + + if arr[mid] == x: + return mid + elif arr[mid] < x: + l = mid + 1 + else: + r = mid-1 + return -1 - #write your code here @@ -17,6 +31,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..9aa183ca 100644 --- a/Exercise_2.py +++ b/Exercise_2.py @@ -1,16 +1,39 @@ # Python program for implementation of Quicksort Sort +# Time Complexity : O(n log n) average, O(n^2) worst +# Space Complexity : O(log n) due to recursion stack +# Did this code successfully run on Leetcode : Yes # give you explanation for the approach def partition(arr,low,high): - - - #write your code here + """ + Rearranges the array by placing the pivot (last element) + in its correct sorted position, with all smaller elements to the left + and greater elements to the right. + Returns the index of the pivot element after partitioning. + """ + pivot = arr[high] # choosing last element as pivot + i = low - 1 # index of smaller element + + for j in range(low, high): + if arr[j] <= pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] # swap + + # place pivot at 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: + # pi is partition index, arr[pi] is now at right place + pi = partition(arr, low, high) + + # Recursively sort elements before and after partition + quickSort(arr, low, pi - 1) + quickSort(arr, pi + 1, high) # Driver code to test above arr = [10, 7, 8, 9, 1, 5] @@ -21,3 +44,5 @@ def quickSort(arr,low,high): print ("%d" %arr[i]), + + diff --git a/Exercise_3.py b/Exercise_3.py index a26a69b8..be59b446 100644 --- a/Exercise_3.py +++ b/Exercise_3.py @@ -1,20 +1,41 @@ # Node class class Node: - # Function to initialise the node object def __init__(self, data): - -class LinkedList: + self.data = data + self.next = None + +class LinkedList: def __init__(self): - + self.head = None def push(self, new_data): - + """ + Insert a new node at the beginning of the list. + """ + new_node = Node(new_data) + new_node.next = self.head + self.head = new_node - # Function to get the middle of - # the linked list + # Function to get the middle of the linked list def printMiddle(self): + """ + Prints the middle element of the linked list. + Uses slow & fast pointer approach. + """ + slow = self.head + fast = self.head + + if self.head is None: + print("The list is empty.") + return + + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + print("The middle element is:", slow.data) # Driver code list1 = LinkedList() @@ -24,3 +45,4 @@ def printMiddle(self): list1.push(3) list1.push(1) list1.printMiddle() + diff --git a/Exercise_4.py b/Exercise_4.py index 9bc25d3d..06845168 100644 --- a/Exercise_4.py +++ b/Exercise_4.py @@ -1,12 +1,45 @@ # Python program for implementation of MergeSort +#Time Complexity O(nlogn) +#Space Complexity O(n) def mergeSort(arr): - - #write your code here - -# Code to print the list -def printList(arr): - - #write your code here + if len(arr) > 1: + mid = len(arr) // 2 # Find the middle + L = arr[:mid] # Left half + R = arr[mid:] # Right half + + # Recursively sort both halves + mergeSort(L) + mergeSort(R) + + # Merge the sorted halves + 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 + + # Copy any remaining elements + while i < len(L): + arr[k] = L[i] + i += 1 + k += 1 + + while j < len(R): + arr[k] = R[j] + j += 1 + k += 1 + + +# Function to print array +def printList(arr): + for i in arr: + print(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..a5f0dd60 100644 --- a/Exercise_5.py +++ b/Exercise_5.py @@ -1,10 +1,43 @@ # Python program for implementation of Quicksort -# This function is same in both iterative and recursive +# Time Complexity : O(n log n) average, O(n^2) worst case +# Space Complexity : O(log n) to O(n) depending on stack size +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No + +# Partition function (same as recursive QuickSort) def partition(arr, l, h): - #write your code here + pivot = arr[h] # choose last element as pivot + i = l - 1 # index of smaller element + + for j in range(l, h): + if arr[j] <= pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] # swap + + arr[i + 1], arr[h] = arr[h], arr[i + 1] + return i + 1 +# Iterative QuickSort def quickSortIterative(arr, l, h): - #write your code here + # Create an auxiliary stack + stack = [(l, h)] + + # Keep popping subarrays while stack is not empty + while stack: + l, h = stack.pop() + if l < h: + # Partition the array + p = partition(arr, l, h) + + # Push left and right subarrays to stack + stack.append((l, p - 1)) + stack.append((p + 1, h)) +if __name__ == "__main__": + arr = [10, 7, 8, 9, 1, 5] + n = len(arr) + quickSortIterative(arr, 0, n - 1) + print("Sorted array is:") + print(arr)