diff --git a/Exercise_1.py b/Exercise_1.py index 3e6adcf4..346d7702 100644 --- a/Exercise_1.py +++ b/Exercise_1.py @@ -1,13 +1,34 @@ +# Time Complexity : O(logn) +# Space Complexity :O(1) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : Used the white board to design the algo and psuedo code which helped to solve it on first try + + +# Your code here along with comments explaining your approach # 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 - - + while l <= r: + '''Setting the mid point''' + m = (l+r)//2 + ''' + If the mid point is the target return the mid point + If the mid point is on the left of the target move the left to the right of midpoint + If the mid point is on the right of the target move the right to the left of the midpoint + ''' + if arr[m] == x: + return m + elif arr[m] < x: + l = m+1 + else: + r = m-1 + + '''Return -1 since the element hasn't been found''' + return -1 # Test array arr = [ 2, 3, 4, 10, 40 ] @@ -17,6 +38,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..6abea054 100644 --- a/Exercise_2.py +++ b/Exercise_2.py @@ -1,17 +1,58 @@ +# Time Complexity : +# Average case: O(nlogn) +# Worst case: O(n^2) +# Space Complexity : +# Average case: O(logn) +# Worst case: O(n) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : +# I watched youtube video to understand the algorithm, made a psuedo code. +# Found the leetcode post helpful http://leetcode.com/discuss/post/1083445/how-quick-sort-works-and-the-problems-th-1h5f/ +# Wrote down the notes for it so I do not forget it again, and memorized the word pivot with quick sort. + # Python program for implementation of Quicksort Sort # give you explanation for the approach def partition(arr,low,high): - + ''' + We choose the first element as a pivot. + We start a wall as second element where all the elements left + of it are always smaller than pivot. + We iterate thought the array and find elements smaller than pivot, swap it with the current position of wall + and move the wall to the right. + Finally we will have the first element as pivot and all the elements smaller than the pivot will be on the + left of the wall. So now we swap the pivot with the element closest to the wall which is exactly the correct + placement of the pivot. + Now all the elements to the left of it are smaller and all the elements to the right are bigger than the pivot. + ''' #write your code here + pivot = arr[low] + leftwall = low + 1 + + for j in range(low+1, high+1): + if arr[j] <= pivot: + arr[leftwall], arr[j] = arr[j], arr[leftwall] + leftwall += 1 + + arr[leftwall - 1], arr[low] = arr[low], arr[leftwall - 1] + return leftwall - 1 # Function to do Quick sort def quickSort(arr,low,high): - + ''' + First we find the correct position of a pivot, then we sort the left half of the pivot + and the right half of the pivot which will eventually sort the entire array as the recurssion reaches to all + the elements of the array. + ''' #write your code here - + if low < high: + p = partition(arr, low, high) + quickSort(arr, low, p-1) + quickSort(arr, p+1, high) + return arr + # Driver code to test above arr = [10, 7, 8, 9, 1, 5] n = len(arr) diff --git a/Exercise_3.py b/Exercise_3.py index a26a69b8..301683b9 100644 --- a/Exercise_3.py +++ b/Exercise_3.py @@ -1,20 +1,63 @@ +# Time Complexity : O(n) +# Space Complexity : O(1) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : No problem, just used the two pointers + # 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 def push(self, new_data): + if self.head is not None: + curr = self.head + + while curr.next is not None: + curr = curr.next + + curr.next = Node(new_data) + + else: + self.head = Node(new_data) # Function to get the middle of # the linked list - def printMiddle(self): + def printMiddle(self): + ''' + p1 moves one node at a time + p2 moves two nodes at a time + When the p2 reaches to the end of the linked list, p1 is at the middle node. + If there are 2 middle nodes, then the p1 will be at the second middle node. (Requirement by leetcode) + odd is the pointer next to the p2. + even is the next to odd which will be the next position of p2. + ''' + p1 = self.head + p2 = self.head.next + + if p1 is None or p2 is None: + return p1.data + + while True: + p1 = p1.next + odd = p2.next + + if odd is None: + return p1.data + + even = p2.next.next + if even is None: + return p1.data + + p2 = even # Driver code list1 = LinkedList() @@ -23,4 +66,4 @@ def printMiddle(self): list1.push(2) list1.push(3) list1.push(1) -list1.printMiddle() +print(list1.printMiddle()) diff --git a/Exercise_4.py b/Exercise_4.py index 9bc25d3d..df458a1a 100644 --- a/Exercise_4.py +++ b/Exercise_4.py @@ -1,18 +1,74 @@ -# Python program for implementation of MergeSort -def mergeSort(arr): +# Time Complexity : O(nlogn) +# Space Complexity : O(n) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : I came up with the merge function with extra space using result array +# But I wanted to merge inplace since that would be efficient, came to know about +# Gap method but didn't spend too much time there and marked as a algorithm to learn +# once I am done with week 4 since it was difficult to understand. + + +# Python program for implementation of MergeSort +def mergeSort(arr, l, h): #write your code here + ''' + If the array is of length 1, do nothing. + Find a midpoint and call mergeSort on both left and right parts of midpoint. + merge both the left and right parts once they are sorted individually. + ''' + if l == h: + return + m = l + (h-l) // 2 + + mergeSort(arr, l, m) + if m+1 < h: + mergeSort(arr, m+1, h) + merge(arr, l, m, h) + +def merge(arr, l, m, h): + ''' + i goes through the left part of the array + j goes through the right part of the array + + We choose the smallest number from both the parts and add it to the results array + once any one part is fully added in the result array, we add the rest of the elements to result + + Finally we put the sorted array result into the appropriate place in the arr array. + ''' + i = l + j = m+1 + result = [] + + while i <= m and j <= h: + if arr[i] <= arr[j]: + result.append(arr[i]) + i+=1 + else: + result.append(arr[j]) + j+=1 + + if i <= m: + for x in arr[i:m+1]: + result.append(x) + + if j <= h: + for x in arr[j:h+1]: + result.append(x) + + for i in range(len(result)): + arr[l+i] = result[i] # Code to print the list def printList(arr): #write your code here - + print(arr) + # driver code to test the above code if __name__ == '__main__': arr = [12, 11, 13, 5, 6, 7] print ("Given array is", end="\n") printList(arr) - mergeSort(arr) + mergeSort(arr, 0, len(arr)-1) print("Sorted array is: ", end="\n") printList(arr) diff --git a/Exercise_5.py b/Exercise_5.py index 1da24ffb..01c980f4 100644 --- a/Exercise_5.py +++ b/Exercise_5.py @@ -1,10 +1,38 @@ +# Time Complexity : +# Average case: O(nlogn) +# Worst case: O(n^2) +# Space Complexity : +# Average case: O(logn) +# Worst case: O(n) +# Did this code successfully run on Leetcode : Yes +# Any problem you faced while coding this : +# I was struggling to do it iteratively as could not understand how to keep track of the +# sorted pivots and how to sort the pivots every time with a different range of elements +# in the array. Then I saw that I can use the partition funtion from previous implementation +# so I just used the white board to come up with the idea of storing the partitions which are unsorted. # Python program for implementation of Quicksort # This function is same in both iterative and recursive def partition(arr, l, h): #write your code here + pivot = arr[l] + leftwall = l + 1 + for j in range(l+1, h+1): + if arr[j] <= pivot: + arr[leftwall], arr[j] = arr[j], arr[leftwall] + leftwall += 1 + + arr[leftwall - 1], arr[l] = arr[l], arr[leftwall - 1] + return leftwall - 1 def quickSortIterative(arr, l, h): #write your code here - + partitions = [(l, h)] + while len(partitions) > 0: + low, high = partitions.pop() + p = partition(arr, low, high) + if low < p-1: + partitions.append((low, p-1)) + if high > p+1: + partitions.append((p+1, high)) \ No newline at end of file